npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@beatsphere/expo-apple-music-kit

v0.1.0

Published

Expo native module for Apple MusicKit — authorization, now playing, playback state, and Apple Music REST API utilities for iOS and Android.

Downloads

51

Readme

@beatsphere/expo-apple-music-kit

Expo native module for Apple MusicKit on iOS and Android. Battle-tested in BeatSphere.

Provides:

  • Native authorization — MusicKit dialog on iOS, OAuth on Android
  • Playback state — currently playing track via SystemMusicPlayer (iOS 16+)
  • User token — for Apple Music REST API requests
  • REST API utilities — recently played, heavy rotation, catalog search, storefront
  • Expo config plugin — auto-configures Info.plist and AndroidManifest

Install

npm install @beatsphere/expo-apple-music-kit

Add the plugin to your app.config.js:

export default {
  plugins: [
    '@beatsphere/expo-apple-music-kit',
    // Or with custom usage description:
    ['@beatsphere/expo-apple-music-kit', {
      appleMusicUsageDescription: 'MyApp needs access to Apple Music to show your listening activity.'
    }],
  ],
};

Run prebuild:

npx expo prebuild --clean

Prerequisites

  1. Apple Developer Account with MusicKit enabled
  2. Developer Token — a JWT signed with your MusicKit private key (Apple docs)
  3. Android: Download MusickitAuthenticationRelease.aar from Apple's MusicKit Android page — this package ships a copy but you may need to update it

Quick Start

Authorization

import {
  isAvailable,
  requestAuthorization,
  getUserToken,
} from '@beatsphere/expo-apple-music-kit';

async function authorize() {
  const available = await isAvailable();
  if (!available) {
    console.log('Apple Music not available');
    return;
  }

  // iOS: shows native dialog. Android: requires developer token.
  const result = await requestAuthorization(DEVELOPER_TOKEN);

  if (result.authorized) {
    // Get user token for API calls
    const userToken = await getUserToken(DEVELOPER_TOKEN);
    console.log('User token:', userToken);
  }
}

Now Playing (iOS 16+)

import { getPlaybackState } from '@beatsphere/expo-apple-music-kit';

const state = await getPlaybackState();

if (state.status === 'playing' && state.track) {
  console.log(`${state.track.name} by ${state.track.artistName}`);
  console.log(`Artwork: ${state.track.artworkUrl}`);
}

Recently Played Tracks

import {
  getRecentlyPlayedTracks,
  getAllRecentlyPlayedTracks,
  simplifyTrack,
  formatArtworkUrl,
} from '@beatsphere/expo-apple-music-kit';

// Single page (max 10)
const response = await getRecentlyPlayedTracks(DEVELOPER_TOKEN, userToken);

// All pages (up to 50)
const allTracks = await getAllRecentlyPlayedTracks(DEVELOPER_TOKEN, userToken);

// Simplified format
const simplified = allTracks.map(simplifyTrack);
// [{ id, name, artist, album, duration, artworkUrl, genres }]

Catalog Search

import { searchCatalog } from '@beatsphere/expo-apple-music-kit';

const results = await searchCatalog(
  DEVELOPER_TOKEN,
  'Daft Punk',
  ['songs', 'albums'],
  'us', // storefront
  10    // limit
);

Heavy Rotation

import { getHeavyRotation } from '@beatsphere/expo-apple-music-kit';

const rotation = await getHeavyRotation(DEVELOPER_TOKEN, userToken);

User Storefront

import { getUserStorefront } from '@beatsphere/expo-apple-music-kit';

const storefront = await getUserStorefront(DEVELOPER_TOKEN, userToken);
// 'us', 'gb', 'jp', etc.

API Reference

Native Module

| Function | Description | |----------|-------------| | isAvailable() | Check if MusicKit is available (iOS 15+ / Apple Music installed on Android) | | isAppleMusicAppInstalled() | Check if Apple Music app is installed (Android) | | requestAuthorization(developerToken?) | Request music access (native dialog on iOS, OAuth on Android) | | getUserToken(developerToken) | Get Music User Token for API calls | | getAuthorizationStatus() | Get current auth status | | getPlaybackState() | Get current playback state + track info (iOS 16+) | | signOut() | Clear stored auth state | | debugToken(token) | Validate JWT format and expiration |

REST API

| Function | Description | |----------|-------------| | getRecentlyPlayedTracks(dev, user, limit?, offset?) | Fetch recent tracks (max 10/page) | | getAllRecentlyPlayedTracks(dev, user) | Fetch all recent tracks (up to 50) | | getRecentlyPlayedResources(dev, user, limit?) | Fetch recent albums/playlists/stations | | getHeavyRotation(dev, user, limit?) | Fetch most played items | | searchCatalog(dev, term, types?, storefront?, limit?) | Search the catalog | | getUserStorefront(dev, user) | Get user's country/region | | simplifyTrack(track) | Transform API track to simple format | | formatArtworkUrl(url, size?) | Replace {w}/{h} in artwork URL template |

Platform Notes

iOS

  • iOS 15+ required for MusicKit authorization
  • iOS 16+ required for getPlaybackState() (SystemMusicPlayer)
  • On iOS < 16, getPlaybackState() returns { status: 'unsupported' }
  • Falls back to SKCloudServiceController for authorization on older iOS

Android

  • Requires the Apple Music app to be installed
  • Uses Apple's official MusicKit Android SDK for OAuth
  • getPlaybackState() is not available on Android (returns unsupported)
  • getAuthorizationStatus() always returns notDetermined (no persistent state)

Developer Token

You need a developer token (JWT) to use Apple Music APIs. Generate one using:

  1. Go to Apple Developer Portal
  2. Create a MusicKit key
  3. Note your Team ID and Key ID
  4. Generate a JWT signed with your private key (ES256 algorithm)

The token should have:

  • iss: Your Team ID
  • iat: Current timestamp
  • exp: Expiration (max 6 months)
  • alg: ES256
  • kid: Your Key ID

License

MIT