Case Study · Personal Project
MusicOne
A minimal web app for saving music locally from Spotify and YouTube — paste a link, pick a format, download.
- Role
- Design & Development
- Year
- 2025
- Type
- Personal Project
- Next.js
- React
- TypeScript
- Tailwind CSS
- Flask
- spotdl
- yt-dlp
- Docker
Problem
Downloading music shouldn't feel like a hack
Most download tools are cluttered, ad-heavy, or only support one platform. I wanted something I would actually use: a clean two-screen flow that works for both Spotify tracks and YouTube videos without sign-up or friction.
Solution
Two screens, one job
MusicOne splits the experience into a home screen (paste URL, pick platform) and a download screen (cover art, metadata, format picker). A Flask backend orchestrates spotdl and yt-dlp, then streams the file back to the browser.
Interface
Two screens, end to end

Home — platform tabs, URL input, and clipboard paste

Download screen — track preview, format selection, and one-click save
Key Features
Built for reliability, not just aesthetics
Dual platform support
Spotify and YouTube tabs with URL validation. Spotify links route through Spotipy for metadata; YouTube uses yt-dlp for titles, thumbnails, and duration.
Format picker
Spotify: MP3 or FLAC. YouTube: MP3, FLAC, or MP4 (video + audio). Each option shows a short quality hint before download.
Reliable file delivery
The backend snapshots the download folder before and after each job, parses yt-dlp output logs, and falls back to mtime detection. Playlists are bundled into a ZIP automatically.
Resilient client
The frontend retries failed requests with timeouts up to 10 minutes for downloads, parses Content-Disposition headers, and triggers blob saves directly in the browser.
Flow
From link to local file
Paste link
Choose Spotify or YouTube, paste or copy a URL from the clipboard, and submit.
Preview track
The download page loads cover art, title, artist, duration, and platform badge.
Pick format
Select MP3, FLAC, or MP4 (YouTube only) based on quality needs.
Download
The backend runs spotdl or yt-dlp, then streams the file — or ZIP for playlists — to the browser.
Architecture
Next.js frontend, Flask download engine
The frontend is a Next.js 16 app with two routes: home for URL input and /download for the preview-and-download flow. The Flask API exposes four endpoints — song-info, download, youtube-info, and download-youtube. Spotify downloads go through spotdl (YouTube Music as audio source); YouTube downloads use yt-dlp with ffmpeg for MP4 merges. The server ships in Docker with Gunicorn, ffmpeg, and Node (required by yt-dlp's JS runtime). Optional proxy support handles cloud IP blocks.
Learnings
Subprocess orchestration is the hard part
The UI is straightforward; the real work is reliably finding output files after CLI tools finish, handling long-running requests without timeouts, and keeping yt-dlp working as YouTube changes. Supporting both spotdl v3 and v4 CLI shapes and building fallback file detection made the backend much more dependable than a naive subprocess wrapper.
Personal project — local demo, not publicly deployed.