Realtime Collaboration
Songbird supports realtime collaboration — multiple users can work on the same project simultaneously. Changes merge automatically using structured, music-aware merge strategies that understand the.bird file format, mixer state, and plugin state.
How It Works
Collaboration is built on three layers:- Collab Server — A lightweight Node.js WebSocket server that manages project rooms, syncs file changes, and merges concurrent edits
- React Client — A WebSocket client in the React UI that auto-pushes changes on every commit and applies remote changes
- Rust State Sync — The
songbird-statecollab modules (collab.rs,collab_state_sync.rs,collab_mixer_sync.rs) handle file reading for push, and write + reload remote files with echo suppression via the sync engine’s guard flags
Quick Start
1. Start the Server
ws://localhost:8765 by default.
2. Create a Room
In Songbird, open the Collaboration panel. Enter the server URL, your name, and click Connect. Then click Create Room — you’ll receive an invite code (e.g.,a1b2c3d4).
3. Invite a Collaborator
Share the invite code. The other user connects to the same server and clicks Join Room with the invite code. They receive the current project files automatically.4. Collaborate
Changes sync automatically:- Edit notes, arrangements, or structure in
.bird→ auto-synced - Move faders, pan knobs, toggle mute/solo → auto-synced
- Tweak plugin parameters → auto-synced
Sync Protocol
Message Types
Sync Flow
Intelligent Merge
The server doesn’t do naive line-by-line text merge. It understands Songbird’s file formats..bird File Merge
The merge engine parses .bird files into a structured tree:
JSON File Merge (daw.state.json, daw.edit.json)
JSON files are merged with recursive deep-merge at the property level:
Conflict Resolution
All conflicts use last-write-wins — the most recent push takes precedence. This is intentionally simple: users naturally learn to avoid stepping on each other’s toes, and the granularity (track + section level) means conflicts are rare in practice.Presence
The server broadcasts real-time presence updates:- Who’s online — list of connected peers
- Cursor position — which section/track/tool each user is working with
- Activity feed — human-readable log of remote changes
Tunnel (Share Session)
The collab server has a built-in Cloudflare Tunnel integration via theuntun npm package. This lets you expose the collab server to the internet with a single click — no manual Cloudflare/Tailscale setup, no port forwarding.
- Click Share Session (Public Tunnel) in the Collaboration panel
- The server spawns a Cloudflare Tunnel on the collab port (default 8765)
- A public
https://URL is generated and displayed — share it with collaborators - Remote peers connect to the tunnel URL instead of
localhost - Click Stop tunnel when done
Optimistic Mixer Sync
Mixer fader changes (volume, pan, mute, solo) are sent optimistically over the WebSocket in real time, bypassing the git commit cycle. This provides ~5-20ms latency for continuous controls like fader drags, compared to ~100-300ms via the commit path.- Outbound: Local changes are throttled to ~30Hz and sent as
mixerUpdatemessages - Inbound: Remote changes are applied directly to the Zustand store
- Local lock: While the user is dragging a slider, remote updates for that control are ignored to prevent jitter
- Source of truth: The git commit layer remains authoritative. Optimistic updates are just a fast preview.
Deployment
The collab server is a single Node.js process with no external dependencies (no database, no Redis). It can run on any machine with Node.js 18+.Local Development
Production (Ubuntu Server)
Audio Assets
Audio samples and recordings are not synced via the collab server. For large audio assets, use a cloud storage bucket (GCS or AWS S3) with Git LFS.Key Files
Design Decisions
- WebSocket from React — JavaScript has native WebSocket support. Running the WebSocket client in React reuses the existing Tauri IPC bridge for file I/O.
- File-level sync, not git-object sync — Sending full file contents (not git objects/patches) is simpler and the files are small text. Each client maintains its own local git history for undo/redo independently.
- Server-side merge — The server runs the structured merge engine. This is simpler than client-side merge and ensures a single source of truth. The tradeoff is offline editing doesn’t auto-merge (but local git undo/redo still works fine).
- Last-write-wins — Simple, predictable, and users rarely conflict at the track/section level in practice. No complex conflict resolution UI needed.
- Echo suppression on apply — When applying remote files, the
undo_redo_in_progressguard flag is set (same mechanism as undo/redo) to prevent echo-pushing the same changes back to the server.