A modern, Spotify-style local music player built with React, TypeScript, and Vite. Upload your MP3 files, organize them into playlists, and enjoy a beautiful music experience with offline-first functionality.
- MP3 Upload & Parsing: Drag-and-drop or click to upload MP3 files
- ID3 Metadata Extraction: Automatically extracts title, artist, album, artwork, duration, year, and genre
- Album Artwork: Displays embedded album art or generates beautiful placeholder SVGs
- Audio Playback: Native HTML5 audio with Media Session API integration
- Queue Management: Add tracks to queue, reorder with drag-and-drop, remove tracks
- Playlist Support: Create, edit, delete, and organize playlists
- Play Modes: Shuffle, repeat (off/one/all), and normal playback
- Dark Theme: Beautiful Spotify-inspired dark interface
- Responsive Design: Works perfectly on desktop, tablet, and mobile
- Progressive Web App (PWA): Installable with offline functionality
- Audio Visualizers: Multiple visualizer options (bars, radial, soft wavefield)
- Smooth Animations: Polished interactions and transitions
- Touch-Friendly: Optimized for mobile with touch gestures
- IndexedDB Storage: All data stored locally in the browser
- Service Worker: Caches app shell and assets for offline use
- Export/Import: Backup and restore your music library
- No Server Required: Runs entirely in the browser
- Media Session API: Lock screen controls, hardware media keys
- Content Deduplication: SHA-256 hashing prevents duplicate uploads
- Drag & Drop: Reorder queue and playlist items
- Search & Filter: Find tracks quickly across your library
- Real-time Updates: Live sync between components and database
- Node.js 18+
- npm or yarn
# Clone the repository
git clone <repository-url>
cd ztm-music-player
# Install dependencies
npm install
# Start development server
npm run dev
# Open http://localhost:5173 in your browser# Build for production
npm run build
# Preview production build
npm run previewztm-music-player/
βββ public/
β βββ icons/ # PWA icons (192x192, 512x512)
β βββ manifest.webmanifest
β βββ sw.js # Service worker
βββ src/
β βββ components/ # React components
β β βββ Artwork.tsx
β β βββ PlayerBar.tsx
β β βββ PlaylistCard.tsx
β β βββ QueueDrawer.tsx
β β βββ SearchBar.tsx
β β βββ SongList.tsx
β β βββ TopBar.tsx
β β βββ UploadDropzone.tsx
β β βββ Visualizer.tsx
β βββ hooks/ # Custom React hooks
β β βββ useIndexedDb.ts
β β βββ usePlayer.tsx
β βββ lib/ # Utility libraries
β β βββ audio.ts
β β βββ id3.ts
β βββ pages/ # Route components
β β βββ NowPlaying.tsx
β β βββ PlaylistDetail.tsx
β β βββ Playlists.tsx
β β βββ Songs.tsx
β β βββ Upload.tsx
β βββ db/ # Database layer
β β βββ indexedDb.ts
β βββ styles/ # Styling
β β βββ tailwind.css
β βββ types.ts # TypeScript definitions
β βββ App.tsx # Main app component
β βββ main.tsx # App entry point
βββ package.json
βββ tailwind.config.ts
βββ tsconfig.json
βββ vite.config.ts
- React 18.3.1 - UI library with hooks and concurrent features
- TypeScript 5.2.2 - Type-safe JavaScript
- Vite 5.3.4 - Fast build tool and dev server
- Tailwind CSS 3.4.6 - Utility-first CSS framework
- React Router 6.25.1 - Client-side routing
- IndexedDB - Browser database for offline storage
- idb - Promise-based IndexedDB wrapper
- music-metadata-browser - ID3 tag parsing for MP3 files
- Service Worker - Offline functionality and caching
- Web App Manifest - PWA installation support
- Font Awesome 6 - Icon library
- Web Audio API - Audio visualization
- Go to the Upload page
- Drag and drop MP3 files or click to select
- Files are automatically parsed for metadata and stored
- Songs page shows all uploaded tracks
- Search and filter your music library
- Click any song to play it
- Go to Playlists page
- Click "New Playlist" to create one
- Add tracks from your library to playlists
- Reorder tracks with drag-and-drop
- Use the mini player at the bottom
- Open the queue drawer to see upcoming tracks
- Visit Now Playing for full-screen experience with visualizers
- Export your library as JSON for backup
- Import libraries from other devices
- Delete tracks and they're automatically removed from playlists
No environment variables required - the app runs entirely client-side.
The app is configured as a PWA with:
- Manifest:
public/manifest.webmanifest - Service Worker:
public/sw.js - Icons:
public/icons/(192x192 and 512x512 PNG files)
- Theme: Modify CSS variables in
src/styles/tailwind.css - Visualizers: Add new visualizer variants in
src/components/Visualizer.tsx - Database Schema: Update types in
src/types.ts
# Install Vercel CLI
npm i -g vercel
# Deploy
vercel
# Or connect your GitHub repo to Vercel for automatic deploymentsThe app can be deployed to any static hosting service:
- Netlify: Drag and drop the
distfolder - GitHub Pages: Use GitHub Actions
- AWS S3: Upload the
distfolder - Firebase Hosting: Use Firebase CLI
The project includes vercel.json for proper SPA routing:
{
"rewrites": [
{
"source": "/(.*)",
"destination": "/index.html"
}
]
}npm run dev # Start development server
npm run build # Build for production
npm run preview # Preview production build
npm run lint # Run ESLint- ESLint: Configured with React and TypeScript rules
- Prettier: Code formatting with Tailwind plugin
- TypeScript: Strict mode enabled
The app uses IndexedDB with the following stores:
- tracks: Music track metadata
- blobs: Audio files and artwork (stored as Blobs)
- playlists: Playlist definitions
- app: Application settings and queue state
Audio not playing:
- Check browser console for errors
- Ensure MP3 files are valid and not corrupted
- Try refreshing the page
PWA not installing:
- Ensure you're using HTTPS (or localhost)
- Check that manifest.webmanifest is accessible
- Verify service worker is registered
Tracks not showing after upload:
- Check browser console for IndexedDB errors
- Try refreshing the page
- Clear browser storage if needed
Visualizer not working:
- Ensure Web Audio API is supported
- Check that audio is actually playing
- Try switching between visualizer modes
- Chrome/Edge: Full support
- Firefox: Full support
- Safari: Full support (iOS 14.5+)
- Mobile: Full support on modern browsers
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit changes:
git commit -m 'Add amazing feature' - Push to branch:
git push origin feature/amazing-feature - Open a Pull Request
- Follow TypeScript strict mode
- Use functional components with hooks
- Maintain responsive design
- Test on multiple browsers
- Update documentation for new features
This project is licensed under the MIT License - see the LICENSE file for details.
- Zero To Mastery - For the inspiration and learning platform
- React Team - For the amazing framework
- Tailwind CSS - For the utility-first CSS approach
- Vite Team - For the lightning-fast build tool
- music-metadata-browser - For ID3 tag parsing capabilities
If you encounter any issues or have questions:
- Check the Troubleshooting section
- Search existing Issues
- Create a new issue with detailed information
- Join the community discussions
Made with β€οΈ for music lovers everywhere