| Crates.io | tauri-plugin-musickit |
| lib.rs | tauri-plugin-musickit |
| version | 0.2.7 |
| created_at | 2025-07-25 07:52:34.491083+00 |
| updated_at | 2025-07-30 18:36:36.297126+00 |
| description | Tauri plugin for Apple MusicKit integration |
| homepage | |
| repository | https://github.com/patrickquinn/tauri-plugin-apple-music-kit |
| max_upload_size | |
| id | 1767293 |
| size | 875,243 |
A Tauri 2 plugin providing comprehensive Apple MusicKit integration for iOS and macOS applications. It allows you to programmatically control music playback, manage queues, handle authorization, and respond to music events through a unified API.
isPlaying(), getCurrentTime(), etc.)Add the plugin to your Tauri app's src-tauri/Cargo.toml:
[dependencies]
tauri-plugin-musickit = "0.2.6"
Install the TypeScript API bindings:
npm install tauri-plugin-musickit
# or
yarn add tauri-plugin-musickit
# or
pnpm add tauri-plugin-musickit
In your src-tauri/src/main.rs, register the plugin:
fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_musickit::init())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
Add the required permissions to your src-tauri/tauri.conf.json:
{
"tauri": {
"allowlist": {
"all": false
},
"bundle": {
"active": true
},
"security": {
"csp": null
},
"plugins": {
"musickit": {
"scope": ["authorize", "getAuthorizationStatus", "initialize", "play", "pause", "stop", "seek", "next", "previous", "skipToItem", "setVolume", "setQueue", "updateQueue", "insertTrackAtPosition", "insertTracksAtPosition", "removeTrackFromQueue", "insertTrackNext", "insertTrackLast", "appendTracksToQueue", "getCurrentTrack", "getPlaybackState", "getQueue", "getUserToken", "getDeveloperToken", "setDeveloperToken", "setUserToken", "getStorefrontId", "getStorefront"]
}
}
}
}
import { musicKit } from 'tauri-plugin-musickit';
// Initialize the plugin
await musicKit.initialize();
// Request authorization
const authResult = await musicKit.authorize();
console.log('Authorization status:', authResult);
// Set developer token (required for authorization)
await musicKit.setDeveloperToken('your-developer-token');
// Control playback
await musicKit.play();
await musicKit.pause();
await musicKit.stop();
await musicKit.next();
await musicKit.previous();
// Seek to specific time
await musicKit.seek(30.5); // 30.5 seconds
// Set volume (iOS: system volume, macOS: may be limited)
await musicKit.setVolume(0.8);
// Get current track
const currentTrack = await musicKit.getCurrentTrack();
console.log('Current track:', currentTrack);
// Get playback state
const playbackState = await musicKit.getPlaybackState();
console.log('Playback state:', playbackState);
// Queue management
const tracks = [
{
id: '123456789',
title: 'Song Title',
artist: 'Artist Name',
album: 'Album Name',
duration: 180.5,
artworkUrl: 'https://example.com/artwork.jpg',
isExplicit: false,
isPlayable: true
}
];
// Set queue
await musicKit.setQueue(tracks, true, 0); // tracks, startPlaying, startPosition
// Update queue
await musicKit.updateQueue(tracks);
// Insert track at position
await musicKit.insertTrackAtPosition(tracks[0], 2);
// Insert tracks at position
await musicKit.insertTracksAtPosition(tracks, 1);
// Remove track from queue
await musicKit.removeTrackFromQueue('123456789');
// Insert track next (after current)
await musicKit.insertTrackNext(tracks[0]);
// Insert track last
await musicKit.insertTrackLast(tracks[0]);
// Append tracks to queue
await musicKit.appendTracksToQueue(tracks);
// Get queue
const queue = await musicKit.getQueue();
console.log('Current queue:', queue);
// Skip to specific track
await musicKit.skipToItem('123456789', true); // trackId, startPlaying
// Convenience methods for quick state checks
const isPlaying = await musicKit.isPlaying();
const isPaused = await musicKit.isPaused();
const currentTime = await musicKit.getCurrentTime();
const duration = await musicKit.getDuration();
const progress = await musicKit.getProgress();
// Listen to events (events now contain complete playback state)
await musicKit.addEventListener('musickit-playback-state-changed', (event) => {
console.log('Playback state changed:', event.playing, event.currentTrack?.title);
});
await musicKit.addEventListener('musickit-track-changed', (event) => {
console.log('Track changed:', event.currentTrack?.title, event.currentTime);
});
await musicKit.addEventListener('musickit-playback-time-changed', (event) => {
console.log('Playback time:', event.currentTime);
});
await musicKit.addEventListener('musickit-queue-changed', (event) => {
console.log('Queue changed:', event.success);
});
// Clean up event listeners
musicKit.removeAllEventListeners();
| Command | Description | Parameters | Returns |
|---|---|---|---|
initialize |
Initialize the MusicKit plugin | None | void |
authorize |
Request Apple Music authorization | None | AuthorizationResponse |
unauthorize |
Unauthorize Apple Music access | None | UnauthorizeResponse |
getAuthorizationStatus |
Check current authorization status | None | AuthorizationStatusResponse |
setDeveloperToken |
Set developer token for authorization | { token: string } |
void |
setUserToken |
Set user token | { token: string } |
void |
getDeveloperToken |
Get developer token | None | string | null |
getUserToken |
Get user token | None | string | null |
getStorefrontId |
Get storefront ID | None | string | null |
getStorefront |
Get storefront information | None | object | null |
play |
Start or resume playback | None | void |
pause |
Pause playback | None | void |
stop |
Stop playback | None | void |
seek |
Seek to specific time | { time: number } |
void |
next |
Skip to next track | None | void |
previous |
Skip to previous track | None | void |
skipToItem |
Skip to specific track | { trackId: string, startPlaying: boolean } |
void |
setVolume |
Set volume (iOS: system volume) | { volume: number } |
void |
setQueue |
Set playback queue | { tracks: MusicKitTrack[], startPlaying: boolean, startPosition: number } |
QueueOperationResponse |
updateQueue |
Update current queue | { tracks: MusicKitTrack[] } |
QueueOperationResponse |
insertTrackAtPosition |
Insert track at position | { track: MusicKitTrack, position: number } |
QueueOperationResponse |
insertTracksAtPosition |
Insert tracks at position | { tracks: MusicKitTrack[], position: number } |
QueueOperationResponse |
removeTrackFromQueue |
Remove track from queue | { trackId: string } |
QueueOperationResponse |
insertTrackNext |
Insert track after current | { track: MusicKitTrack } |
QueueOperationResponse |
insertTrackLast |
Insert track at end | { track: MusicKitTrack } |
QueueOperationResponse |
appendTracksToQueue |
Append tracks to queue | { tracks: MusicKitTrack[] } |
QueueOperationResponse |
getCurrentTrack |
Get current track information | None | MusicKitTrack | null |
getPlaybackState |
Get current playback state | None | PlaybackState |
getQueue |
Get current queue | None | QueueResponse |
isPlaying |
Check if currently playing | None | boolean |
isPaused |
Check if currently paused | None | boolean |
getCurrentTime |
Get current playback time | None | number |
getDuration |
Get track duration | None | number |
getProgress |
Get playback progress (0-1) | None | number |
| Event | Description | Payload |
|---|---|---|
musickit-playback-state-changed |
Playback state changed | PlaybackState (complete state object) |
musickit-track-changed |
Current track changed | PlaybackState (complete state object) |
musickit-playback-time-changed |
Playback time updated | { currentTime: number } |
musickit-queue-changed |
Queue was modified | { success: boolean } |
interface MusicKitTrack {
id: string;
title: string;
artist: string;
album: string;
duration: number;
artworkUrl?: string;
isExplicit: boolean;
isPlayable: boolean;
}
interface AuthorizationResponse {
status: 'authorized' | 'notAuthorized' | 'error';
error?: string;
}
interface UnauthorizeResponse {
status: 'unauthorized' | 'error';
error?: string;
}
interface AuthorizationStatusResponse {
status: 'authorized' | 'notAuthorized' | 'notInitialized';
}
interface QueueResponse {
items: MusicKitTrack[];
position: number;
}
interface QueueOperationResponse {
success: boolean;
error?: string;
}
// Complete playback state object (used by both state and track change events)
interface PlaybackState {
playing: boolean;
paused: boolean;
currentTrack: {
id: string;
title: string;
artistName: string;
albumName: string;
genreNames: string;
durationInMillis: number;
artwork: string;
} | null;
currentTime: number;
duration: number;
progress: number;
queuePosition: number;
shuffleMode: 'on' | 'off';
repeatMode: 'none' | 'all';
volume: number;
}
interface StateUpdateEvent extends PlaybackState {}
interface TrackChangeEvent extends PlaybackState {}
interface PlaybackTimeEvent {
currentTime: number;
}
interface QueueChangeEvent {
success: boolean;
}
interface MusicKitEventMap {
'musickit-playback-state-changed': StateUpdateEvent;
'musickit-track-changed': TrackChangeEvent;
'musickit-playback-time-changed': PlaybackTimeEvent;
'musickit-queue-changed': QueueChangeEvent;
}
# Clone the repository
git clone https://github.com/patrickquinn/tauri-plugin-musickit.git
cd tauri-plugin-musickit
# Install dependencies
bun install
# Build the project
bun run build
# Run checks
bun run check
# Build iOS Swift code
cd ios
xcodebuild -scheme MusicKitPlugin -destination 'generic/platform=iOS' build
# Build macOS Swift code
cd macos
xcodebuild -scheme MusicKitPlugin -destination 'generic/platform=macOS' build
Licensed under either of
at your option.
git checkout -b feature/amazing-feature)git commit -m 'Add some amazing feature')git push origin feature/amazing-feature)tauri-plugin-musickit on crates.iotauri-plugin-musickit on npm