Git for music co-production. Push WAV stems from LMMS, review pull requests in the browser, and resolve conflicts with side-by-side waveform comparison.
Built for UNIHACK 2026.
DEMO VIDEO: TRACKSYNC
- Create a project in the web app and copy the Project ID.
- Connect LMMS via the TrackSync sidebar plugin — select a feature branch (not
main). - Push — LMMS renders sample tracks to WAV and uploads them to the backend.
- Review — open a pull request on the web to compare branches side by side.
- Merge — resolve any conflicts (same track name, different audio) and merge into
main. - Pull — download the merged tracks back into LMMS.
Each project is stored as a local Git repo on the server (tracks/*.wav per branch). The backend auto-mixes stems into a main preview track (main.mp3).
- LMMS plugin: C++ / Qt sidebar — connect, push, pull, create PRs
- Frontend: React, Tailwind CSS, Wavesurfer.js (deployed on Vercel)
- Backend: FastAPI, GitPython, FFmpeg (deployed on Railway)
- Storage: Supabase (optional) with local JSON fallback
| Service | URL |
|---|---|
| Web app | https://frontend-sigma-inky-bbx27rv9il.vercel.app |
| Backend API | https://backend-production-8b2a.up.railway.app |
In LMMS, set the API URL to the web app URL (no /projects suffix). Vercel proxies API requests to Railway.
From the repo root:
# Backend
cd backend
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
uvicorn main:app --reload --port 8000
# Frontend (new terminal)
cd frontend
npm install
npm run devOr run both together from the repo root (requires backend venv already set up):
npm install
npm run devCopy .env.example to .env and fill in values if using Supabase locally:
cp .env.example .envBackend (Railway):
- Root directory:
backend - Start command:
uvicorn main:app --host 0.0.0.0 --port $PORT - Mount a persistent volume at
/app/datafor Git repos and audio - Set
CORS_ORIGINS,SUPABASE_URL,SUPABASE_KEYin Railway variables
Frontend (Vercel):
- Root directory:
frontend frontend/vercel.jsonproxies/projectsand/audioto the Railway backend- Set
VITE_API_URLin Vercel env vars if not using the proxy rewrites
npm run deploy:frontend # production
npm run deploy:frontend:preview # preview| Method | Path | Description |
|---|---|---|
| GET | /projects |
List projects |
| POST | /projects |
Create project |
| GET/PATCH/DELETE | /projects/{id} |
Get / update / delete project |
| POST | /projects/{id}/cover |
Upload album cover |
| GET | /projects/{id}/dashboard |
Dashboard data (tracks, history, main mix) |
| GET/POST | /projects/{id}/branches |
List / create branches |
| POST | /projects/{id}/push-files |
Push WAV stems to a branch |
| GET | /projects/{id}/clone |
Clone manifest for LMMS pull |
| POST | /projects/{id}/pull |
Pull latest (server-side git) |
| GET | /projects/{id}/history |
Commit timeline |
| GET/POST | /projects/{id}/prs |
List / create pull requests |
| GET | /projects/{id}/pr/{prId} |
Pull request detail + live diff |
| POST | /projects/{id}/pr/{prId}/merge |
Merge with conflict resolutions |
| GET | /projects/{id}/conflict?track=X&pr=Y |
Conflict audio URLs |
| POST | /projects/{id}/audio-diff |
Compare two WAV files |
| GET | /audio/{id}/branch/{branch}/{path} |
Stream audio from a git branch |
- FFmpeg (optional): mixes stems to MP3; Python WAV fallback used if unavailable
- Node 18+ for frontend
- Python 3.9+ for backend
- LMMS with TrackSync sidebar plugin (in
lmms/submodule) for DAW integration
MIT