# VibeSonic VibeSonic is a lightweight, self-hosted music/media server written in Go. Single binary, SQLite storage, server-rendered Bootstrap 5 templates, dark mode by default, minimal JavaScript, no external services (no Redis, no message broker, no microservices). It implements the **original Subsonic REST API through version 1.16.1**, in full, plus a set of **OpenSubsonic extensions**, so it works with existing Subsonic/OpenSubsonic client apps, alongside a complete server-rendered web UI for browser use. See [`docs/subsonic-compatibility.md`](docs/subsonic-compatibility.md) for the endpoint-by-endpoint matrix and [`docs/client-compatibility.md`](docs/client-compatibility.md) for real-client testing status. ## Features - SQLite storage (WAL mode, foreign keys, versioned migrations) - Native authentication (Argon2id, HTTP-only session cookies, CSRF) and optional Navidrome-style external authentication via a trusted reverse-proxy header, gated on the real TCP peer address — see [`docs/external-auth.md`](docs/external-auth.md) - A library scanner: multiple music folders, incremental rescans, new/changed/deleted/renamed detection, bounded worker pool - Real metadata extraction via `ffprobe` (multi-artist/genre, MusicBrainz IDs, ReplayGain, embedded artwork/lyrics, sort fields) - Direct streaming with HTTP range support, plus real ffmpeg-backed transcoding (mp3/opus/aac) and HLS segmenting, bounded concurrency, cancelled on client disconnect - Structured lyrics: plain, line-synced, and (where the source provides it) word/syllable-level timing, exposed via the `songLyrics` OpenSubsonic extension and rendered in the web player with click-to-seek and active-line highlighting - Sonic similarity: real audio-feature analysis (tempo, loudness, spectral shape, chroma) computed during scanning, used for similar-track lookups and path-finding between songs - Optional MusicBrainz/Cover Art Archive metadata enrichment (off by default — VibeSonic works fully offline otherwise) - Podcasts (RSS subscriptions, bounded background downloads, restart recovery), Internet radio stations, shares (public, no-login-required links), bookmarks, and multi-device play queues - A real jukebox backed by `mpv`'s JSON IPC — server-side playback, not a simulation; cleanly unavailable if `mpv` isn't installed - API keys, with the full Subsonic per-user permission model (admin/settings/stream/download/upload/playlist/cover art/comment/ podcast/share/jukebox/video-conversion roles, plus per-user music folder access) - A server-rendered, dark-mode, keyboard-friendly web UI covering browsing, search, playlists (including M3U import/export), favorites, a persistent player with shuffle/repeat and the Media Session API, and a full admin section - `/healthz` and `/readyz` ## Quick start ``` go build -o vibesonic ./cmd/vibesonic VIBESONIC_SESSION_SECRET=$(openssl rand -hex 32) ./vibesonic ``` Then open `http://localhost:8080` — on a fresh database you'll land on the setup wizard, which creates the administrator account, your first music folder, and kicks off the first scan. `ffmpeg`/`ffprobe` should be on `PATH` (or pointed to via `VIBESONIC_FFMPEG_PATH`/`VIBESONIC_FFPROBE_PATH`) for metadata reading, cover art extraction, and transcoding/HLS to work. `mpv` should be on `PATH` (or pointed to via `VIBESONIC_MPV_PATH`) for the jukebox to be available — without it, `jukeboxControl` returns a clear "unavailable" error rather than pretending to work. Point any Subsonic/OpenSubsonic client at `http://:8080` (base URL only, no `/rest` suffix — clients construct that themselves) with a VibeSonic username/password, or an API key generated from account settings. ### Docker ``` docker compose up -d ``` See [`docker-compose.yml`](docker-compose.yml) — mount your music directory read-only at `/music` and set `VIBESONIC_SESSION_SECRET`. Docker is convenient but never required; see [`docs/deployment.md`](docs/deployment.md) for running natively. ### systemd See [`systemd/vibesonic.service`](systemd/vibesonic.service) and [`docs/deployment.md`](docs/deployment.md) for install steps and reverse-proxy examples (Caddy/nginx/Traefik). ## Configuration VibeSonic is configured entirely through `VIBESONIC_*` environment variables — see [`docs/configuration.md`](docs/configuration.md) for the full list and defaults. There is no separate config file. ## Documentation - [`docs/architecture.md`](docs/architecture.md) — how the pieces fit together - [`docs/configuration.md`](docs/configuration.md) — every environment variable - [`docs/external-auth.md`](docs/external-auth.md) — trusted reverse-proxy authentication - [`docs/subsonic-compatibility.md`](docs/subsonic-compatibility.md) — protocol endpoint/extension status - [`docs/client-compatibility.md`](docs/client-compatibility.md) — real-client testing tracker - [`docs/deployment.md`](docs/deployment.md) — native/Docker/systemd/reverse-proxy deployment - [`docs/security.md`](docs/security.md) — security-relevant design decisions - [`docs/backup.md`](docs/backup.md) — what to back up and how (SQLite WAL caveats included) ## Development ``` go fmt ./... go vet ./... go test ./... ``` Most tests exercise real SQLite databases and, where relevant, the real `ffmpeg`/`ffprobe` binaries (skipped automatically if not installed). No mocks are used for the database.