A fully functional music player inspired by Spotify's design, built with modern React tooling
🎧 Play, pause, skip tracks, manage favorites, and scrub through songs — all wrapped in a clean dark UI. Built with React, Tailwind CSS v4, and Zustand for lightweight global state.
React Spotify Clone provides a complete music player experience:
Play and pause tracks with a circular control button, album art overlay, and smooth icon transitions.
Seek to any point in a song using a draggable progress bar with live current/total time display.
Skip to the next or previous song with queue wrapping — the last track loops back to the first.
Like and unlike any song. All liked tracks are collected on a dedicated Favorites page.
Instant visual feedback via react-hot-toast whenever a song is added or removed from favorites.
Sidebar collapses gracefully on smaller screens; player controls adapt to mobile viewports.
Developer profile page with social links, tooltips, and branded hover states.
✅ Real-time playback state
✅ Race-condition-safe playback
✅ No stale state
✅ One-click copy
✅ Netlify-ready
✅ Fully dark UI
- React 18 — Modern UI framework with hooks
- Vite — Lightning-fast dev server and build tool
- Tailwind CSS v4 — Utility-first styling via
@tailwindcss/vite - Zustand — Minimal global state for playback and favorites
- React Router DOM v6 — Client-side routing
- React Hot Toast — Lightweight toast notifications
- React Icons — Icon library (Bootstrap, Material, Font Awesome sets)
- Node.js ≥ 18
- npm or yarn
-
Clone the repository
git clone https://github.com/parham-ab/react-spotify-clone.git cd react-spotify-clone -
Install dependencies
npm install
-
Start the development server
npm run dev
Open http://localhost:5173 in your browser.
-
Build for production
npm run build
-
Preview production build
npm run preview
- Browse the track list on the Songs page
- Click any song row or album cover to start playback
- Control playback from the header bar — play/pause, previous, next
- Scrub the progress bar to seek within the current track
- Like a song using the heart icon; find all liked songs under Favorites
- Navigate between pages using the sidebar
└── spotify/
├── public/
│ ├── _redirects
│ └── spotify.png
└── src/
├── assets/
│ ├── img/
│ ├── music/
│ └── styles/
│ └── index.css
├── components/
│ └── Layout/
│ ├── index.jsx
│ ├── Header.jsx
│ ├── Sidebar.jsx
│ └── Footer.jsx
├── constants/
│ └── sidebar-data.js
├── pages/
│ ├── contact-us/
│ │ ├── constants/
│ │ │ └── links.js
│ │ └── index.jsx
│ ├── Favorites.jsx
│ ├── Song.jsx
│ └── SongsList.jsx
├── providers/
│ └── AudioProvider.jsx
├── routes/
│ └── index.jsx
├── store/
│ └── spotifyStore.js
├── App.jsx
└── main.jsx
Global state is handled by a single Zustand store (src/store/spotifyStore.js):
songData— array of all tracks withactive,isPlaying, andisFavoriteflagssongTrack— the raw<audio>DOM node registered byAudioProvideron mountplayHandle(id)— toggles play/pause for the active song, or loads and plays a new onenextSongHandle / prevSongHandle— advances or rewinds the queue with wrappingtoggleFavorite(id)— flipsisFavoriteand fires a toast notificationgetCurrentSong()— derives the active song live fromsongData(no stale snapshot)
The <audio> element lives in AudioProvider and is registered via setSongTrack, making it available to all store actions without prop-drilling or React context.
The project is configured for deployment on Netlify. The public/_redirects file ensures React Router's client-side routing works correctly on page refresh:
/* /index.html 200
Contributions are welcome! Feel free to:
- Report bugs
- Suggest new features or pages
- Improve existing components
- Enhance documentation
Parham Abolghasemi — Frontend Developer · UI/UX Designer
- GitHub: @parham-ab
- LinkedIn: parham-abolghasemi
- Website: parham-ab.netlify.app
- Email: parham.abg1@gmail.com
This project is open source and available under the MIT License.
Happy Listening! 🎵


