Music Hub Architecture
Version: v0.3.0
Last Updated: 2026-07-26
Overview
Music Hub is a local-first music system built around these repositories:
desktop/— Electron hub app, Docker server runtime, and local APImobile/— iOS and Android companion applanding/— public site, beta access, buyer recovery, licensing backenddocs/— public documentation siterelay/— managed relay service code (gordo-labs/music-hub-relay(opens in a new tab)); lives beside the hub in the umbrella workspace. Today’s product uses Personal Private network plus optional Cloudflare / public link on the hub; managed relay is a future phase (see Building).
The desktop hub is the product runtime source of truth. The other surfaces orbit around it.
Plugins
Music Hub has a permissioned, Desktop-first plugin platform for core and third-party extensions. Plugins use a versioned manifest, explicit grants and a constrained Host API rather than direct access to the Desktop runtime, database, local filesystem or mobile pairing state. Community bundles are verified and activated as declarative data only in this preview; they do not execute bundle JavaScript. Mobile does not execute third-party plugins. See Plugins for the public contract and release status.
Runtime shape
desktop/
electron/main.cjs Electron shell + splash + app lifecycle
src/index.ts Express server bootstrap
src/api/index.ts Canonical API entrypoint
src/api/routes.ts Main route surface
src/database/ Active native SQLite runtime
src/scanner/ Folder scanning
src/metadata/ Embedded tag extraction
src/enrichment/ Background enrichment pipeline
src/streaming/ Direct + HLS playback
src/auth/ Pairing + refresh-token flow
src/media-access/ Signed media/share sessions
src/tunnel/ Cloudflare + Personal Private network (Iroh/sovereign)
ui-src/ React rendererThe historical desktop/src/core/database tree still exists as an archived sql.js prototype, but the active runtime uses desktop/src/database.
Core data flow
Scan and ingest
- User adds one or more folders.
- Scanner walks the filesystem and compares it against the indexed set.
- Metadata extraction reads embedded tags and artwork.
- The desktop DB stores tracks, artists, albums, playlists, saved state, playback state, and enrichment data.
- The UI receives updates over SSE.
Playback
- Clients read the shared playback session from
/api/playback/session. - Local-safe formats can use direct streaming.
- Remote and public-share playback use HLS or signed media routes.
- Playback session, queue, and history are persisted in the hub DB so desktop and mobile can restore state.
Commercial and entitlement flow
- The landing owns the current public beta access flow.
- Purchase/recovery/license records live outside the desktop runtime.
- The desktop activates against that licensing backend.
- Remote access stays enabled only while desktop entitlement validation remains valid.
Sharing
- A share page loads only public bootstrap data.
- Bootstrap returns a short-lived
shareSessionIdandmediaToken. - The share client renews the session with
/api/share/session/heartbeat. - Audio/artwork requests are authorized through the issued media token.
Networking and trust model
The desktop backend now has an explicit trust boundary:
- Loopback requests are treated as local admin traffic.
- Forwarded or non-loopback requests are treated as remote.
- Remote
/api/*access is auth-by-default.
Public exceptions are deliberately small:
GET /api/pingGET /api/info- pair/refresh endpoints
- share bootstrap and share heartbeat endpoints
Sensitive local-only flows include:
- pairing arm status
- QR generation helpers
- database rebuild
Pairing model
Remote access is no longer anonymous.
- Desktop user arms pairing locally.
- QR/share config includes a one-time
pairingCodewhile armed. - Mobile exchanges that code for access + refresh tokens.
- Mobile silently refreshes access tokens and stores auth state per hub/origin.
This keeps Personal Private network / public remote access usable without falling back to a single long-lived static secret for every client.
Licensing model
The current entitlement rule is:
- LAN / Wi-Fi use can remain available without remote entitlement
- remote playback and remote share-protected flows depend on a valid desktop entitlement
The desktop caches entitlement state locally, but the gating model is anchored in server-signed entitlement data rather than a plain local boolean alone.
Storage and recovery
Current desktop persistence is native SQLite via better-sqlite3-multiple-ciphers.
Key behaviors:
- DB path defaults to
~/.music-hub/music.db - startup checks
user_versionand integrity databaseHealthis surfaced through/api/infoand/api/settings- incompatible or faulted DBs are preserved and archived instead of being silently wiped
- local rebuild is explicit through
POST /api/database/rebuild
Remote access
Supported remote paths today:
- Personal Private network (always on in Settings → Remote)
- optional Cloudflare / public remote link
Tailscale / embedded tsnet is no longer a product Settings path (0.3.0+).
The server binds to loopback by default and only broadens network exposure when LAN/remote access is explicitly enabled.
Public web surface
There is no general-purpose browser control app for remote users. The public browser surface today is:
- landing marketing site
- docs site
- standalone share pages for playlists, artists, albums, and tracks
Share pages are intentionally narrow: bootstrap-only data fetch, tokenized playback, and no access to the full protected library API.
Current status
What is true in the current codebase:
- desktop DB runtime is native SQLite, not sql.js
- playback/session persistence is shared between clients
- remote auth uses pair + refresh tokens
- public share pages use signed bootstrap/media sessions
- landing participates in the buyer/license/recovery stack, not just marketing
- degraded DB states surface explicitly and can be rebuilt locally
- docs and landing are separate Next-based surfaces
relay/is a separate service repository (managed relay path; future phase)