{"_id":"@beatsphere/expo-apple-music-kit","name":"@beatsphere/expo-apple-music-kit","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@beatsphere/expo-apple-music-kit","version":"0.1.0","description":"Expo native module for Apple MusicKit — authorization, now playing, playback state, and Apple Music REST API utilities for iOS and Android.","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc","prepublishOnly":"tsc"},"keywords":["expo","apple-music","musickit","react-native","now-playing","music","streaming","ios","android"],"author":{"name":"BeatSphere","email":"hello@beatsphere.app"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/Beatsphere/expo-apple-music-kit.git"},"bugs":{"url":"https://github.com/Beatsphere/expo-apple-music-kit/issues"},"homepage":"https://github.com/Beatsphere/expo-apple-music-kit#readme","peerDependencies":{"expo":">=51.0.0","expo-modules-core":">=1.0.0","react":">=18.0.0","react-native":">=0.73.0"},"peerDependenciesMeta":{"@react-native-async-storage/async-storage":{"optional":true}},"devDependencies":{"expo-modules-core":"^2.3.0","typescript":"^5.5.0"},"gitHead":"21873d003f93ffb9b6faa7c2bb271912af1d3577","_id":"@beatsphere/expo-apple-music-kit@0.1.0","_nodeVersion":"24.12.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-7yut9KaCvLMExMrV9zoj3a23KYb7ZO5okC7Q7ukafGcTQwY4dYpCqvyfLYlmbUf3YdHuR1lumoTUj0U/bvu5EA==","shasum":"9d870c6521409b5cd5c7620a2b7350098865a51b","tarball":"https://registry.npmjs.org/@beatsphere/expo-apple-music-kit/-/expo-apple-music-kit-0.1.0.tgz","fileCount":31,"unpackedSize":285455,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCDwwYvE+D4YLxEHmGJQBWndHtQP5ksU/duPEpNKxR/bQIgEEKS7jSQx9B1Lptr9wfyzcpqdkPfN7eyryR/8s6RfPE="}]},"_npmUser":{"name":"ayushh2k","email":"rustichouse042@gmail.com"},"directories":{},"maintainers":[{"name":"ayushh2k","email":"rustichouse042@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/expo-apple-music-kit_0.1.0_1776969107101_0.6209401698678958"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-23T18:31:46.955Z","0.1.0":"2026-04-23T18:31:47.304Z","modified":"2026-04-23T18:31:47.589Z"},"maintainers":[{"name":"ayushh2k","email":"rustichouse042@gmail.com"}],"description":"Expo native module for Apple MusicKit — authorization, now playing, playback state, and Apple Music REST API utilities for iOS and Android.","homepage":"https://github.com/Beatsphere/expo-apple-music-kit#readme","keywords":["expo","apple-music","musickit","react-native","now-playing","music","streaming","ios","android"],"repository":{"type":"git","url":"git+https://github.com/Beatsphere/expo-apple-music-kit.git"},"author":{"name":"BeatSphere","email":"hello@beatsphere.app"},"bugs":{"url":"https://github.com/Beatsphere/expo-apple-music-kit/issues"},"license":"MIT","readme":"# @beatsphere/expo-apple-music-kit\n\nExpo native module for Apple MusicKit on iOS and Android. Battle-tested in [BeatSphere](https://beatsphere.live).\n\nProvides:\n\n- **Native authorization** — MusicKit dialog on iOS, OAuth on Android\n- **Playback state** — currently playing track via SystemMusicPlayer (iOS 16+)\n- **User token** — for Apple Music REST API requests\n- **REST API utilities** — recently played, heavy rotation, catalog search, storefront\n- **Expo config plugin** — auto-configures Info.plist and AndroidManifest\n\n## Install\n\n```bash\nnpm install @beatsphere/expo-apple-music-kit\n```\n\nAdd the plugin to your `app.config.js`:\n\n```js\nexport default {\n  plugins: [\n    '@beatsphere/expo-apple-music-kit',\n    // Or with custom usage description:\n    ['@beatsphere/expo-apple-music-kit', {\n      appleMusicUsageDescription: 'MyApp needs access to Apple Music to show your listening activity.'\n    }],\n  ],\n};\n```\n\nRun prebuild:\n\n```bash\nnpx expo prebuild --clean\n```\n\n### Prerequisites\n\n1. **Apple Developer Account** with MusicKit enabled\n2. **Developer Token** — a JWT signed with your MusicKit private key ([Apple docs](https://developer.apple.com/documentation/applemusicapi/generating_developer_tokens))\n3. **Android**: Download `MusickitAuthenticationRelease.aar` from [Apple's MusicKit Android page](https://developer.apple.com/musickit/android/) — this package ships a copy but you may need to update it\n\n## Quick Start\n\n### Authorization\n\n```tsx\nimport {\n  isAvailable,\n  requestAuthorization,\n  getUserToken,\n} from '@beatsphere/expo-apple-music-kit';\n\nasync function authorize() {\n  const available = await isAvailable();\n  if (!available) {\n    console.log('Apple Music not available');\n    return;\n  }\n\n  // iOS: shows native dialog. Android: requires developer token.\n  const result = await requestAuthorization(DEVELOPER_TOKEN);\n\n  if (result.authorized) {\n    // Get user token for API calls\n    const userToken = await getUserToken(DEVELOPER_TOKEN);\n    console.log('User token:', userToken);\n  }\n}\n```\n\n### Now Playing (iOS 16+)\n\n```tsx\nimport { getPlaybackState } from '@beatsphere/expo-apple-music-kit';\n\nconst state = await getPlaybackState();\n\nif (state.status === 'playing' && state.track) {\n  console.log(`${state.track.name} by ${state.track.artistName}`);\n  console.log(`Artwork: ${state.track.artworkUrl}`);\n}\n```\n\n### Recently Played Tracks\n\n```tsx\nimport {\n  getRecentlyPlayedTracks,\n  getAllRecentlyPlayedTracks,\n  simplifyTrack,\n  formatArtworkUrl,\n} from '@beatsphere/expo-apple-music-kit';\n\n// Single page (max 10)\nconst response = await getRecentlyPlayedTracks(DEVELOPER_TOKEN, userToken);\n\n// All pages (up to 50)\nconst allTracks = await getAllRecentlyPlayedTracks(DEVELOPER_TOKEN, userToken);\n\n// Simplified format\nconst simplified = allTracks.map(simplifyTrack);\n// [{ id, name, artist, album, duration, artworkUrl, genres }]\n```\n\n### Catalog Search\n\n```tsx\nimport { searchCatalog } from '@beatsphere/expo-apple-music-kit';\n\nconst results = await searchCatalog(\n  DEVELOPER_TOKEN,\n  'Daft Punk',\n  ['songs', 'albums'],\n  'us', // storefront\n  10    // limit\n);\n```\n\n### Heavy Rotation\n\n```tsx\nimport { getHeavyRotation } from '@beatsphere/expo-apple-music-kit';\n\nconst rotation = await getHeavyRotation(DEVELOPER_TOKEN, userToken);\n```\n\n### User Storefront\n\n```tsx\nimport { getUserStorefront } from '@beatsphere/expo-apple-music-kit';\n\nconst storefront = await getUserStorefront(DEVELOPER_TOKEN, userToken);\n// 'us', 'gb', 'jp', etc.\n```\n\n## API Reference\n\n### Native Module\n\n| Function | Description |\n|----------|-------------|\n| `isAvailable()` | Check if MusicKit is available (iOS 15+ / Apple Music installed on Android) |\n| `isAppleMusicAppInstalled()` | Check if Apple Music app is installed (Android) |\n| `requestAuthorization(developerToken?)` | Request music access (native dialog on iOS, OAuth on Android) |\n| `getUserToken(developerToken)` | Get Music User Token for API calls |\n| `getAuthorizationStatus()` | Get current auth status |\n| `getPlaybackState()` | Get current playback state + track info (iOS 16+) |\n| `signOut()` | Clear stored auth state |\n| `debugToken(token)` | Validate JWT format and expiration |\n\n### REST API\n\n| Function | Description |\n|----------|-------------|\n| `getRecentlyPlayedTracks(dev, user, limit?, offset?)` | Fetch recent tracks (max 10/page) |\n| `getAllRecentlyPlayedTracks(dev, user)` | Fetch all recent tracks (up to 50) |\n| `getRecentlyPlayedResources(dev, user, limit?)` | Fetch recent albums/playlists/stations |\n| `getHeavyRotation(dev, user, limit?)` | Fetch most played items |\n| `searchCatalog(dev, term, types?, storefront?, limit?)` | Search the catalog |\n| `getUserStorefront(dev, user)` | Get user's country/region |\n| `simplifyTrack(track)` | Transform API track to simple format |\n| `formatArtworkUrl(url, size?)` | Replace `{w}`/`{h}` in artwork URL template |\n\n## Platform Notes\n\n### iOS\n- **iOS 15+** required for MusicKit authorization\n- **iOS 16+** required for `getPlaybackState()` (SystemMusicPlayer)\n- On iOS < 16, `getPlaybackState()` returns `{ status: 'unsupported' }`\n- Falls back to `SKCloudServiceController` for authorization on older iOS\n\n### Android\n- Requires the **Apple Music app** to be installed\n- Uses Apple's official [MusicKit Android SDK](https://developer.apple.com/musickit/android/) for OAuth\n- `getPlaybackState()` is not available on Android (returns `unsupported`)\n- `getAuthorizationStatus()` always returns `notDetermined` (no persistent state)\n\n## Developer Token\n\nYou need a developer token (JWT) to use Apple Music APIs. Generate one using:\n\n1. Go to [Apple Developer Portal](https://developer.apple.com/account/resources/authkeys/list)\n2. Create a **MusicKit** key\n3. Note your **Team ID** and **Key ID**\n4. Generate a JWT signed with your private key (ES256 algorithm)\n\nThe token should have:\n- `iss`: Your Team ID\n- `iat`: Current timestamp\n- `exp`: Expiration (max 6 months)\n- `alg`: ES256\n- `kid`: Your Key ID\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-40341dedd3ebe4caef59031abbd768b8"}