Paste a Spotify, YouTube, or other music link and get the same song on all platforms. Share music with anyone regardless of their preferred streaming service.
- End the platform wars: No more "I don't use that app" responses
- Universal peace: Share music without starting arguments about streaming services
- Save friendships: Because losing friends over Spotify vs Apple Music is just silly
-
Install dependencies:
npm install
-
Configure API keys in
.env:SPOTIFY_CLIENT_ID=your_spotify_client_id SPOTIFY_CLIENT_SECRET=your_spotify_client_secret YOUTUBE_API_KEY=your_youtube_api_key
-
Build and start:
npm run all:start
Visit http://localhost:3000 to use the app.
Main commands:
npm run all:start- Build everything and start servernpm run build- Build all packagesnpm run test- Run testsnpm run lint- Lint all code
Development workflow:
# Start client dev server (after building common)
npm run build:common
npm run dev --workspace=@muc/client
# Start server in another terminal
npm run build && npm run startnpm workspaces monorepo with shared code architecture:
- common/ - Core business logic shared between client and server
- Platform API clients (Spotify, YouTube, Deezer, iTunes)
- Normalized track types and data models
- Media service abstractions
- API route definitions and request/response types
- server/ - Express API that imports media services from common
- Thin API layer over common's BackendMediaService
- Caching and rate limiting
- client/ - Vue 3 frontend that imports types and utilities from common
- Uses common's API client directly
- Shares track identifiers and normalized data types
- cli/ - Command-line tools
The common package enables type safety and code reuse - both client and server work with the same data structures and business logic, just with different service implementations (backend vs API client).
Endpoints at /api/:
POST /api/spotify/search- Search SpotifyPOST /api/youtube/search- Search YouTubePOST /api/spotify/track- Get track detailsPOST /api/youtube/video- Get video details
Docker:
docker build -t muc .
docker run -p 3000:3000 --env-file .env mucFly.io:
fly secrets set SPOTIFY_CLIENT_ID=xxx SPOTIFY_CLIENT_SECRET=xxx YOUTUBE_API_KEY=xxx
fly deployFrontend: Vue 3, Vite, Pinia (state management), Vitest (testing)
Backend: Express.js, Node.js 22, NodeCache (in-memory caching)
Shared: TypeScript, ESBuild (bundling), npm workspaces
Deployment: Docker, Fly.io
Dev Tools: ESLint, Prettier, Morgan (logging), p-limit (concurrency)
Way overengineered for what is essentially a "find song on other apps" button, but hey, I had fun building it 🤓
This is a complete rewrite of the original MUC which was built with Vue 2
and vanilla JavaScript. The original version is fully unmaintained but lives on in the vue2 branch for posterity.
Why rewrite? Because apparently a simple Vue 2 app wasn't enterprise-grade enough. But more seriously, updating dependencies became a chore with figuring out which libraries I can upgrade while still being on Vue 2.