An open-source web music player powered by YouTube Music.
Built with Next.js Β· Tailwind CSS Β· Zustand Β· Web Audio API
Arythm is a full-featured music streaming app that runs entirely in your browser. It connects to the YouTube Music catalog through the InnerTube API, giving you access to millions of songs with a clean, modern interface. No YouTube Music subscription required.
It works across desktop, tablet, and mobile, and can be installed as a PWA so it behaves like a native app.
- Stream any song from the YouTube Music catalog in high-quality audio
- Instant playback -- audio URLs are resolved via the InnerTube Player API in ~200ms, with yt-dlp as a fallback
- Full-screen player with blurred album artwork background and ambient color extraction via ColorThief
- Queue management -- shuffle, repeat (one/all/off), and remove songs from the queue
- Volume normalization via Web Audio API so quiet and loud songs play at similar levels
- OS media controls -- play/pause/skip from your lock screen, notification shade, or Bluetooth headphones
- Playback speed -- 0.25x to 4x
- Local file support -- drag and drop or pick audio files from your device
When you play a single song, Arythm automatically fills your queue with related songs from the same genre. It uses YouTube Music's radio API (RDAMVM{videoId}) as a seed, giving you continuous listening without lifting a finger.
Arythm preloads the next 2 songs as in-memory blobs and pre-resolves URLs for the next 5 as soon as the current song starts. If your internet drops mid-session, the next songs play seamlessly from the local cache. No buffering, no interruption.
- 4 lyrics providers -- LrcLib, KuGou, Musixmatch, and YouTube Music
- Synced lyrics with Apple Music-style karaoke display (line-by-line highlighting, smooth font/color transitions)
- Tap to seek -- click any lyric line to jump to that point in the song
- Fast path -- returns synced lyrics as soon as the first provider responds (
Promise.any), no waiting for slower providers - Pre-warm -- lyrics are fetched in the background when a song starts playing, so they're instant when you open the panel
- Personalized homepage -- Quick Picks, Song Suggestions, Mix Carousels, Playlist Recommendations, and Mood tiles, all powered by YouTube Music's home feed
- Real-time search with autocomplete suggestions
- Filtered results -- browse by Songs, Albums, Artists, or Playlists
- Mood & genre browsing -- Chill, Workout, Focus, Night, Drive, Romance, and more
- Artist, album, and playlist detail pages with full track listings
- Personalized content when signed in with a YouTube Music cookie
- Like songs and access them from your library
- Recently played history on the homepage
- Create and manage playlists (syncs with YouTube Music if authenticated)
- Listening statistics -- most played songs and artists
- All library data is persisted in localStorage -- no account required
- Responsive layout -- sidebar on desktop, bottom tab bar on mobile
- Dark theme with glassmorphism design (frosted glass cards, subtle transparency)
- Ambient background -- dominant color extracted from album art, blurred across the entire page
- Installable as a PWA on any device
- Keyboard shortcuts -- spacebar to play/pause, arrow keys to seek, and more
- Framer Motion animations throughout
Arythm is a two-part system:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Arythm (Frontend) β
β β
β Next.js app hosted on Vercel β
β Handles: UI, search, browsing, queue, lyrics, library β
β Talks to: YouTube Music InnerTube API (server-side) β
β Arythm-Proxy (for CORS-safe audio streaming) β
β LrcLib, KuGou, Musixmatch (for lyrics) β
ββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββ΄βββββββββββββββ
β Fast path (InnerTube) β Fallback (yt-dlp)
β POST /api/innertube/player β GET /stream?v=VIDEO_ID
β β 200ms URL resolution β β 3-10s URL resolution
β β GET /stream?url=...&v=... β
βΌ βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Arythm-Proxy (Backend) β
β β
β Express server hosted on Render β
β Handles: Piping audio bytes from googlevideo.com with CORS β
β Resolving URLs via yt-dlp (fallback only) β
β Request deduplication (one yt-dlp per video) β
β Caching resolved URLs for 5 hours β
β Forwarding Range headers for seeking β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Why a separate proxy? YouTube's audio servers (googlevideo.com) don't set CORS headers, so browsers block direct playback. The proxy fetches audio server-side and pipes it back with proper CORS headers.
| Layer | Technology | Purpose |
|---|---|---|
| Framework | Next.js 16 (App Router) | Server-side rendering, API routes, file-based routing |
| UI | React 19 | Component architecture |
| Language | TypeScript 5 | Type safety across the entire codebase |
| Styling | Tailwind CSS v4 + Framer Motion | Utility-first CSS + smooth animations |
| State | Zustand | Lightweight stores for player, library, and settings |
| Audio | HTML5 Audio + Web Audio API | Playback engine + volume normalization |
| Music API | YouTube Music InnerTube | Search, browse, home feed, radio, player, artist/album pages |
| Lyrics | LrcLib + KuGou + Musixmatch + YouTube Music | 4-provider synced and plain lyrics |
| Audio Proxy | Express + yt-dlp | CORS-safe audio streaming with URL resolution fallback |
| Color | ColorThief | Dominant color extraction for ambient backgrounds |
| Icons | Lucide React | Consistent icon set |
- Node.js 20 or later
- npm (comes with Node.js)
git clone https://github.com/aryanjsx/Arythm.git
cd Arythm
npm installCreate a .env file in the project root:
YOUTUBE_COOKIE=""
AUDIO_PROXY_URL="https://your-proxy.onrender.com"
NEXT_PUBLIC_AUDIO_PROXY_URL="https://your-proxy.onrender.com"| Variable | Required | Description |
|---|---|---|
YOUTUBE_COOKIE |
No | Your YouTube Music cookie. Enables personalized home feed, recommendations, lyrics from YouTube Music, and library sync. Without it, you still get generic content. |
AUDIO_PROXY_URL |
Yes | URL of your Arythm-Proxy instance (server-side usage). |
NEXT_PUBLIC_AUDIO_PROXY_URL |
Yes | Same URL, exposed to the browser for client-side streaming. |
How to get your YouTube Music cookie
- Open music.youtube.com in Chrome and sign in
- Press
F12to open DevTools, go to the Network tab - Click on any request to
music.youtube.com - In the request headers, find the
Cookieheader and copy its full value - Paste it as
YOUTUBE_COOKIEin your.envfile
This cookie is used server-side only and never sent to the browser.
npm run devOpen http://localhost:3000 in your browser.
The frontend needs the Arythm-Proxy running separately. See the Arythm-Proxy README for setup instructions.
src/
βββ app/ # Next.js App Router
β βββ page.tsx # Homepage
β βββ search/page.tsx # Search results
β βββ album/[id]/page.tsx # Album detail
β βββ artist/[id]/page.tsx # Artist detail
β βββ playlist/[id]/page.tsx # Playlist detail
β βββ browse/[id]/page.tsx # Mood/genre category
β βββ library/page.tsx # User library
β βββ history/page.tsx # Play history
β βββ stats/page.tsx # Listening statistics
β βββ settings/page.tsx # Preferences
β βββ mood-and-genres/page.tsx # Browse by mood & genre
β βββ login/page.tsx # YouTube Music authentication
β βββ icon.tsx # Dynamic favicon
β βββ api/
β βββ innertube/ # YouTube Music API proxy
β β βββ browse/route.ts # Home feed, artist, album, playlist, moods
β β βββ search/route.ts # Search + autocomplete suggestions
β β βββ player/route.ts # Stream URLs, formats, loudness
β β βββ next/route.ts # Radio queue (related songs)
β β βββ playlist/route.ts # Playlist CRUD, like/unlike
β βββ lyrics/route.ts # 4-provider lyrics (LrcLib, KuGou, Musixmatch, YTM)
β βββ stream/ # Audio stream helpers
β βββ auth/route.ts # YouTube auth check
β
βββ components/
β βββ home/ # Homepage sections
β β βββ HeroSection.tsx # Greeting banner
β β βββ QuickPickGrid.tsx # Song card grid
β β βββ SongSuggestionRow.tsx # Horizontal song list
β β βββ MixCarousel.tsx # YouTube Music mixes
β β βββ PlaylistSuggestionRow.tsx # Playlist recommendations
β β βββ PlaylistCarousel.tsx # Mixed-content carousel
β β βββ MoodCategoryRow.tsx # Mood tiles
β β βββ RecentlyPlayed.tsx # Recently played grid
β βββ player/ # Audio player
β β βββ player-wrapper.tsx # Root: mounts mini + full player
β β βββ mini-player.tsx # Bottom bar controls
β β βββ full-player.tsx # Full-screen player with artwork
β β βββ player-controls.tsx # Play/pause, seek, volume
β β βββ queue-panel.tsx # Queue list
β β βββ lyrics-view.tsx # Synced lyrics display
β β βββ AmbientBackground.tsx # Blurred artwork background
β βββ music/ # Reusable music item components
β βββ layout/ # Sidebar, header, bottom nav
β
βββ lib/
β βββ audio/player.ts # PlayerService singleton
β β # HTML5 Audio + Web Audio API
β β # InnerTube-first URL resolution (~200ms)
β β # Prefetch next 2 songs as blobs
β β # Pre-resolve next 5 URLs via InnerTube
β β # Auto-queue related songs
β β # Pre-warm lyrics on song change
β β # Media Session integration
β βββ innertube/ # YouTube Music InnerTube client
β β βββ innertube.ts # API functions (search, browse, player, next)
β β βββ parsers.ts # Response β typed objects (Song, Album, etc.)
β β βββ client.ts # Client configs (WEB_REMIX, ANDROID, IOS, etc.)
β β βββ auth.ts # Cookie auth + SAPISID hash generation
β β βββ stream.ts # youtubei.js session management
β βββ lyrics/ # Lyrics providers
β βββ lrclib.ts # LrcLib (synced + plain)
β βββ kugou.ts # KuGou (synced + plain)
β βββ musixmatch.ts # Musixmatch (synced + plain)
β βββ youtube-music.ts # YouTube Music (plain, via InnerTube)
β
βββ stores/ # Zustand state management
β βββ player-store.ts # Queue, playback state, repeat/shuffle
β βββ library-store.ts # Liked songs, recently played, playlists
β βββ settings-store.ts # Theme, preferences
β
βββ hooks/ # React hooks
β βββ use-player.ts # Initialize PlayerService, expose controls
β βββ use-lyrics.ts # Fetch/cache lyrics, sync with playback time
β βββ use-keyboard-shortcuts.ts # Global keyboard bindings
β βββ use-local-files.ts # Local audio file playback
β
βββ types/ # TypeScript definitions
βββ music.ts # Song, Album, Artist, Playlist, Lyrics, etc.
βββ innertube.ts # InnerTube request/response types
- User clicks a song anywhere in the app
playSong(song)sets the queue and increments_playbackGenerationin the Zustand storePlayerServicedetects the generation change and callsonPlaybackTriggered(song)- URL resolution (fast path): calls
/api/innertube/playerto get a directgooglevideo.comaudio URL (~200ms) - Passes the URL to the proxy:
GET /stream?url=<direct_url>&v=<videoId>-- the proxy just pipes bytes, no yt-dlp needed - If InnerTube fails, falls back to
GET /stream?v=<videoId>where the proxy resolves via yt-dlp audio.play()is called and the browser starts playback as data arrives- After playback starts:
- Auto-queue fires if only 1 song in queue -- fills queue with related songs via InnerTube radio API
- Prefetch downloads the next 2 songs as blobs for offline resilience
- Pre-resolve warms InnerTube URL cache for the next 5 songs
- Lyrics pre-warm fires the lyrics API request so lyrics are cached before the user opens the panel
All 4 providers are queried in parallel. Promise.any returns immediately when the first provider delivers synced lyrics. If none have synced lyrics, it falls back to Promise.all and picks the best plain text result. Results are cached server-side for 10 minutes and client-side per session.
The homepage fetches YouTube Music's home feed via InnerTube and categorizes each section:
| Section | Detection | Component |
|---|---|---|
| Quick Picks | First all-songs section | QuickPickGrid |
| Song Suggestions | Remaining all-songs sections | SongSuggestionRow |
| Mixes | All-playlist sections with "mix"/"radio" in title or radio IDs | MixCarousel |
| Playlists | All-playlist sections (non-mix) | PlaylistSuggestionRow |
| Mixed | Sections with albums + playlists + songs | PlaylistCarousel |
| Moods | Static mood/genre tiles | MoodCategoryRow |
- InnerTune / OuterTune -- inspiration
- LrcLib -- synchronized lyrics
- KuGou -- lyrics provider
- Musixmatch -- lyrics provider
- yt-dlp -- YouTube audio extraction (fallback)
This project is for educational purposes only. It is not affiliated with or endorsed by Google. YouTube Music is a trademark of Google LLC.
Made by aryanjsx