A modern, responsive music player powered by YouTube Music. Features local playlists, favorites, real-time synchronized lyrics, and a fully customizable glassmorphism UI. Optimized for both desktop and mobile experiences.
AetherPulse|Music is a fullstack React + Node.js application that streams music via YouTube Music's Innertube API. It offers a complete music discovery and playback experience with local playlist management, synced lyrics, keyboard-driven controls, and a theme system supporting light, dark, and custom color presets.
- Advanced Search: Find tracks, playlists, albums, and artists directly from YouTube Music with filter tabs and search history.
- Dynamic Player: Full-featured playback with queue management, seeking, volume control, shuffle, and repeat modes (none / one / all).
- Synchronized Lyrics: Real-time lyric sync via LRCLIB and YouTube Music, featuring karaoke-style highlighting, auto-scroll, and click-to-seek.
- Local Playlists: Create, edit, and manage personal playlists stored locally in JSON.
- YT Import: Import any YouTube Music playlist into your local library for offline-style editing.
- Favorites & History: Track favorites and recently played songs via browser
localStorage. - Customizable Themes: 7+ visual presets (Classic Dark, Light, Cyberpunk, Tokyo Night, AMOLED, etc.) plus custom accent colors and background overrides.
- Keyboard Shortcuts:
/β Focus searchSpaceorKβ Toggle play/pauseArrowLeft/ArrowRightβ Seek Β±10s (Shift + Arrow to change track)ArrowUp/ArrowDownβ Volume Β±5%Mβ Mute/unmuteLβ Toggle lyrics modalQβ Toggle queue modal
- Responsive Design: Mobile-first layout with collapsible sidebar, bottom player, and glassmorphism effects.
- Google OAuth: Optional authentication for accessing your personal YouTube Music library.
βββββββββββββββββββ HTTP / REST ββββββββββββββββββββ HTTPS βββββββββββββββββββ
β React Client β ββββββββββββββββββββΊ β Express Server β βββββββββββββββΊ β YouTube Music β
β (Port 5000) β β (Port 3001) β β (Innertube) β
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β β
β localStorage β local JSON
βΌ βΌ
βββββββββββββββββββ ββββββββββββββββββββ
β User Prefs, β β localPlaylists β
β Favorites, β β .json β
β Recent Plays β ββββββββββββββββββββ
βββββββββββββββββββ
The frontend is a Single Page Application (SPA) built with React 19 and React Router 7.
App.js
βββ LanguageProvider (Context)
βββ ThemeProvider (Context)
βββ BrowserRouter
βββ AppShell
βββ Sidebar (Navigation)
βββ Header (Search, Notifications, Auth)
βββ Outlet (Route-specific screen)
β βββ MusicPage (Home, Discover, Playlists, Artists, Albums)
β βββ ArtistDetailPage
β βββ AlbumDetailPage
β βββ InsightsPage
β βββ SettingsPage
βββ Player (Fixed bottom playback bar)
βββ QueueModal
βββ LyricsModal
State Management
- Global UI State:
ThemeContext(theme, colors, glass effects) andLanguageContext(i18n: EN / PL). - Global App State:
AppShellcentralizes player state (now playing, queue, favorites, recent plays) via ReactuseState/useRefand exposes it to child routes throughOutletcontext. - Server State:
useAuthSessionandusePageDatacustom hooks handle async data fetching with loading/error states. - Persistence:
localStoragestores theme preferences, player volume, favorites, recent plays, and search history.
Media Playback
- Audio playback uses the YouTube IFrame API with a hidden player div.
- The player communicates state changes (PLAYING, PAUSED, ENDED) back to React via callbacks.
- The Media Session API integrates with OS-level media controls (play/pause, prev/next, seek).
The backend is a modular Express 5 application using factory-pattern routers.
server/index.js
βββ CORS & Session Middleware
βββ Content-Security-Policy Headers
βββ Router Mounting
β βββ /api/auth β createAuthRouter (Google OAuth, sessions)
β βββ /api/ytmusic β createYtmusicRouter (Search, artists, albums, playlists)
β βββ /api/local/ β createLocalPlaylistsRouter (JSON-based local playlists)
β βββ /api/lyrics β createLyricsRouter (LRCLIB + YTM lyrics aggregation)
β βββ /api/page β createPagesRouter (Screen data aggregation)
βββ Static File Serving (production)
Design Patterns
- Factory Routers: Each route module exports a factory function that receives dependencies (e.g.,
ytclient,oauth2Client) and returns a freshexpress.Router()instance. This avoids shared mutable state between router instances. - Async Wrapper:
utils/helpers.jsprovides awrap(fn)utility that catches async errors and returns standardized500JSON responses, eliminating repetitivetry/catchblocks. - Shared Utilities:
helpers.jscentralizes common logic like thumbnail resolution (pickThumbnailUrl), media normalization (toMediaItem), queue enrichment (toQueueItem), and local playlist persistence (loadLocalPlaylists,saveLocalPlaylists).
YouTube Music Integration
server/ytmusic.jsimplements a custom Innertube API client using Node.jshttps.- It sends authenticated
POSTrequests tomusic.youtube.com/youtubei/v1/with aWEB_REMIXclient context. - Responses are parsed via deep-safe navigation utilities (
nav,getText,getThumbnails) to handle YouTube's deeply nested JSON structure.
- Search: User types in
AppShellβ debounced API call to/api/ytmusic/searchβ backend calls Innertube β parsed results returned β React renders search dropdown. - Playback: User clicks a track β
AppShell.play()loadsvideoIdinto hidden YT player β YT IFrame API events update React state (time, duration, play/pause) β UI re-renders progress bar and controls. - Lyrics:
LyricsModalmounts β fetches/api/lyrics?q=...β backend tries LRCLIB first, falls back to YTM β lyrics are parsed into timed lines βcurrentTimestate drives active line highlighting and auto-scroll. - Page Data: Route mounts (e.g.,
/playlists) βusePageDatacalls/api/page/playlistsβ backend aggregates YTM library + local playlists into a single screen payload βMusicPagerenders sections.
| Layer | Technology |
|---|---|
| Frontend | React 19.2, React Router DOM 7.14, Tailwind CSS 3.4 |
| State | React Context API, useState, useRef, useCallback |
| Backend | Node.js, Express 5.2, Express Session 1.19 |
| Auth | Google OAuth 2.0 (googleapis 165.0.0) |
| Music API | YouTube Music Innertube (server/ytmusic.js) |
| Lyrics API | LRCLIB.net + YouTube Music |
| Storage | Browser localStorage, local JSON file |
| Tooling | react-scripts 5.0, concurrently 9.2, cross-env |
AetherPulseMusic-main/
βββ public/ # Static assets, PWA manifest
βββ server/
β βββ index.js # Express app entry point
β βββ ytmusic.js # YouTube Music Innertube client & parsers
β βββ routes/
β β βββ auth.js # Google OAuth & session routes
β β βββ ytmusic.js # YTM data routes (search, artists, albums...)
β β βββ localPlaylists.js # Local JSON playlist CRUD
β β βββ lyrics.js # Lyrics aggregation (LRCLIB + YTM)
β β βββ pages.js # Screen data aggregation
β βββ utils/
β βββ helpers.js # Async wrapper, media mappers, playlist I/O
βββ src/
β βββ App.js # Root component with providers & routing
β βββ index.css # Global styles & CSS variables
β βββ components/
β β βββ AppShell.js # Main layout, player state, search
β β βββ Player.js # Bottom playback controls
β β βββ Sidebar.js # Navigation sidebar
β β βββ QueueModal.js # Queue management modal
β β βββ LyricsModal.js # Synced lyrics display
β β βββ Toast.js # Notification system
β β βββ ThemeSettings.js # Theme customization modal
β β βββ music/ # Music-specific UI (MediaCard, QueueTable...)
β β βββ ...
β βββ screens/
β β βββ MusicPage.js # Generic page renderer (home, playlists, etc.)
β β βββ ArtistDetailPage.js
β β βββ AlbumDetailPage.js
β β βββ InsightsPage.js
β β βββ SettingsPage.js
β βββ contexts/
β β βββ ThemeContext.js # Theme, colors, glass effects
β β βββ LanguageContext.js # i18n (EN / PL)
β βββ hooks/
β β βββ useAuthSession.js # Auth state & session refresh
β β βββ usePageData.js # Screen data fetching
β βββ lib/
β β βββ api.js # HTTP client helpers
β β βββ energy.js # Track energy estimation
β βββ data/
β βββ musicData.js # Static navigation config
βββ .env.example
βββ package.json
βββ tailwind.config.js
- Node.js 18+
- npm or yarn
# Clone the repository
git clone <repo-url>
cd AetherPulseMusic-main
# Install dependencies
npm install
# Configure environment
cp .env.example .env
# Edit .env and fill in your Google OAuth credentials (optional)# Start both frontend and backend
npm run dev- Frontend:
http://localhost:5000 - Backend API:
http://localhost:3001
You can also run them separately:
npm run client # React dev server only
npm run server:dev # Express backend with auto-reload (Node --watch)npm run build # Create optimized React build
npm run server # Start production Express server| Variable | Description | Required |
|---|---|---|
BACKEND_PORT |
Backend development port (default: 3001) |
No |
BACKEND_URL |
Backend URL for proxying (default: http://localhost:3001) |
No |
FRONTEND_URL |
Frontend URL for OAuth redirects (default: http://localhost:5000) |
No |
SESSION_SECRET |
Express session secret | Yes (production) |
GOOGLE_CLIENT_ID |
Google OAuth Client ID | No |
GOOGLE_CLIENT_SECRET |
Google OAuth Client Secret | No |
GOOGLE_CALLBACK_URL |
OAuth callback URL (default: http://localhost:3001/api/auth/google/callback) |
No |
REACT_APP_API_BASE_URL |
Frontend API base URL | No |
Note: Google OAuth is optional. Without it, the app works in anonymous mode with local playlists and favorites.
| Endpoint | Description |
|---|---|
GET /api/auth/session |
Get current auth status |
GET /api/auth/google |
Initiate Google OAuth flow |
POST /api/auth/logout |
Destroy session |
GET /api/ytmusic/search?q=...&filter=... |
Search YTM |
GET /api/ytmusic/artist/:id |
Artist details |
GET /api/ytmusic/album/:id |
Album details |
GET /api/ytmusic/playlist/:id |
Playlist tracks |
GET /api/lyrics?q=...&videoId=... |
Fetch lyrics (LRCLIB + YTM) |
GET /api/local/playlists |
List local playlists |
POST /api/local/playlists |
Create local playlist |
GET /api/page/:key |
Get aggregated screen data |
| Script | Description |
|---|---|
npm run dev |
Start frontend + backend concurrently |
npm run client |
Start React dev server (localhost:5000) |
npm run server |
Start production backend |
npm run server:dev |
Start backend with Node --watch |
npm run build |
Build optimized production bundle |
npm test |
Run React test suite |
Contributions are welcome! Please check CONTRIBUTING.md for guidelines.
Before submitting a PR, ensure the application starts correctly:
npm run devThis project is licensed under the MIT License.