Problem statement
Can I make a faster, more responsive and fun version of Apple Music for the web? This thought came about when using the official Apple Music app on MacOS or in a browser which can sometimes be laggy or clunky to use. That's how apple-music-web was made.
Feasibility
Apple maintains the Apple Music API and a JS library called MusicKit to interact with the API. The Apple Music API unfortunately doesn't have all the endpoints to fully replicate the official Apple Music app.
| Area | Possible | Not possible |
|---|---|---|
| Catalog | Read all types, search, charts | — |
| Library | Read, search, add items | Remove items |
| Playlists | Create, add tracks to the end | Rename, reorder, remove tracks, delete |
| Folders | Read, create a playlist in one | Create, move |
| Ratings | Love, dislike, clear | — |
| Favorites | Add | Remove (not in the docs) |
| Personal | Recently played, recommendations, Replay | Friends, social |
| Playback | Play, seek, volume, queue, shuffle, repeat, stations | Lossless, Atmos, queue on other devices |
| Lyrics | — | Any lyrics |
Scope
Given the API's limitations, the scope of this project became clear:
A web-based Apple Music player to just play music.
That means building views to show playlists, albums, and artists, a library wide search and playback control.
Tech stack
The stack for this project is relatively simple:
| Concern | Choice |
|---|---|
| Language | React 19 + TypeScript 6 |
| Framework | TanStack Start |
| Routing | TanStack Router (file-based) |
| Data fetching | TanStack Query + MusicKit |
| Global shortcuts | TanStack Hotkeys |
| Devtools | TanStack Devtools |
| Styling | Tailwind CSS 4 + CVA |
| Components | coss on Base UI |
| Animation | Motion |
| Build and runtime | Vite 8 + Bun |
I've opted for client side rendering with TanStack Start as I have no need for server actions and MusicKit implicitly makes you use it client side despite not being a client side library explicitly.
Viewing media
apple-music-web has views for the Recently Played, Playlists, Albums, and Artists. This allows users to view and navigate through their music library.
The sidebar is hideable and allows navigation between the aformentioned views. It also allows the user to switch themes between light, dark and system, and also logging out.
Albums and playlists have detail views that show more information about the media like the track list, release year, genre(s) and if available a description. The background also changes to a gradient based on the album's artwork.
Artists get their own view that show their top songs, all their albums, singles & EPs, Apple Music playlists and other media that the artist appears on.
Blazing fast search
Searching for media can be done anytime by using the shortcut Cmd K. This allows you to search your library but also Apple Music's catalog. The users playlists, albums and arists are indexed, so searching is instant.
Playback controls
The player controls allow the user to pause/play, skip tracks, shuffle and repeat the queue or song. It has a collapsed and expanded view to highlight the current song.
Shortcuts
The app also supports keyboard shortcuts. I chose shortcuts that are common with other web applications like Cmd K or [ for toggling the sidebar.
Devtools
To make development easier, I created two devtools that I was able to incorporate into the existing devtools from TanStack. The Apple Authentication devtools allows me to easily be in a signed in/out state without actaully signing out and back in everytime. The player provides information about the current song that is playing, the queue, notifications and DRM.
This helped making sure the right actions were performed like nuking the cache when signed out and playing a song and populating the queue has the documentation of MusicKit is barely useable.
Closing thoughts
It was though working with MusicKit as the documentation didn't line up with expectations nor the documetation of the Apple Music API. Queueing a song was the initial hurdle as DRM is required to play music, but the library doesn't say that with an error, it just wouldn't work.
The sidebar implementation is custom and inspired by Linear's sidebar. If you've ever used Linear, you'll know what I mean with an interaction like the sidebar.
Notifications are also supported so when the web app is in the background, it will show you what song it will play now. Unfortunately, the implementation is not ideal as it doesn't always show a notification and the icon is the Safari icon because it's running in a browser.
You can check out the project on Github or try it yourself at apple-music-but-faster.amar.sh.