Music URI converter https://muc.anirbanmu.com/
  • TypeScript 76.5%
  • Vue 20.9%
  • CSS 1.1%
  • Dockerfile 0.9%
  • HTML 0.5%
  • Other 0.1%
Find a file
2026-04-11 12:59:41 -07:00
.github Merge pull request #237 from anirbanmu/dependabot/github_actions/all-actions-b1823d654a 2026-03-14 02:40:30 -07:00
.vscode Create Vue3 app in packages/client & prove that it can consume packages/common 2025-06-22 00:02:48 -07:00
packages upgrade dependencies 2026-04-11 12:58:19 -07:00
.dockerignore create preliminary dockerfile 2025-08-11 01:57:14 -07:00
.gitignore guess we need this for typescript + image assets? 2025-08-12 02:33:19 -07:00
.prettierignore prettier stuff 2025-07-19 21:10:17 -07:00
.tool-versions upgrade to latest node24 2026-03-14 01:42:11 -07:00
Dockerfile debian13 distroless seems available 2025-11-04 19:17:33 -08:00
eslint.config.ts eslint + prettier stuff 2025-07-19 22:11:27 -07:00
fly.toml allowing the 1 replica to be suspended seems like it causes huge delay on first request, so setting min to 1 to see if this avoids the issue 2025-08-12 23:52:21 -07:00
LICENSE mit license 2025-08-13 02:26:25 -07:00
package-lock.json upgrade dependencies 2026-04-11 12:58:19 -07:00
package.json upgrade dependencies 2026-04-11 12:58:19 -07:00
prettier.config.js fixing more eslint/prettier stuff 2025-07-20 02:12:59 -07:00
README.md remove specific api endpoints since now client just uses the uber api 2025-09-15 22:40:07 -07:00

🎵 muc - Music URI Converter

Checks

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.

What it does

  • 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

🚀 Quick Start

  1. Install dependencies:

    npm install
    
  2. 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
    
  3. Build and start:

    npm run all:start
    

Visit http://localhost:3000 to use the app.

🛠️ Development

Main commands:

  • npm run all:start - Build everything and start server
  • npm run build - Build all packages
  • npm run test - Run tests
  • npm 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 start

🏗️ Architecture

npm 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).

API

Endpoints at /api/:

  • POST /api/spotify/search - Search Spotify
  • POST /api/youtube/search - Search YouTube
  • POST /api/spotify/track - Get track details
  • POST /api/youtube/video - Get video details

🚢 Deployment

Docker:

docker build -t muc .
docker run -p 3000:3000 --env-file .env muc

Fly.io:

fly secrets set SPOTIFY_CLIENT_ID=xxx SPOTIFY_CLIENT_SECRET=xxx YOUTUBE_API_KEY=xxx
fly deploy

🔧 Tech Stack

Frontend: 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 🤓

📚 History

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.