@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
Maintainers
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-kitAdd 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 --cleanPrerequisites
- Apple Developer Account with MusicKit enabled
- Developer Token — a JWT signed with your MusicKit private key (Apple docs)
- Android: Download
MusickitAuthenticationRelease.aarfrom 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
SKCloudServiceControllerfor 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 (returnsunsupported)getAuthorizationStatus()always returnsnotDetermined(no persistent state)
Developer Token
You need a developer token (JWT) to use Apple Music APIs. Generate one using:
- Go to Apple Developer Portal
- Create a MusicKit key
- Note your Team ID and Key ID
- Generate a JWT signed with your private key (ES256 algorithm)
The token should have:
iss: Your Team IDiat: Current timestampexp: Expiration (max 6 months)alg: ES256kid: Your Key ID
License
MIT
