Navidrome turns a folder of music files into a streaming service you run yourself. Point it at your library and it scans the tags, then serves a modern web player and an API that works with dozens of existing Subsonic-compatible apps on iPhone, Android and desktop. Each user gets their own playlists, favourites and play counts, and it transcodes on the fly, including to Opus, so a lossless library still streams well over mobile data.
It is written in Go, uses very little memory and runs comfortably on a Raspberry Pi, a NAS or a cheap VPS. It handles very large libraries, compilations and multi-disc box sets properly, reads lyrics from sidecar files and tags, and watches the library for changes. Optional integrations pull artist art and info from Last.fm and Deezer and scrobble to Last.fm and ListenBrainz.
Navidrome is GPL-3.0, at about 24,400 stars and v0.64.2 when scanned. It plays music you already own; it does not download or find music for you.
- Repository: github.com/navidrome/navidrome
- Licence: GPL-3.0 (GNU General Public License v3.0)
- Language: Go. Stars: 24.4K. Forks: 1,776. Last push: Oct 26, 2026.
- Scan: safe, Oct 26, 2026, commit ec2e0a9
Who it is for
People with a large MP3 or FLAC collection who want it on their phone without uploading it to a cloud service, and self-hosters looking for a light music server for a family or a home lab.
Getting started
1. Run it with Docker, pointing it at your music and a data folder
docker run -d --name navidrome --restart=unless-stopped --user $(id -u):$(id -g) -v /path/to/music:/music -v /path/to/data:/data -p 4533:4533 -e ND_LOGLEVEL=info deluan/navidrome:latest2. Open it and create the first account, which becomes the admin
open http://localhost:4533Pre-built binaries for Linux, macOS, Windows and Raspberry Pi are on the releases page, and macOS users can brew install navidrome. To listen on a phone, install any Subsonic-compatible app and give it your server address.
Safety scan
We cloned navidrome/navidrome at commit ec2e0a9 on Oct 26, 2026 and ran the checks described on the GitHub Tools page: credential patterns, decode-and-execute code, install-time scripts, committed binaries, risky CI workflows, every host the code talks to, known vulnerabilities in pinned dependencies, and project hygiene. A person read every hit. This is what we found.
- No secrets, no committed binaries and no suspicious code. The one pattern hit is the Makefile's developer target that installs golangci-lint with curl | sh; it is a lint tool for contributors and never runs when you install Navidrome.
- Navidrome sends an anonymous Insights report to insights.navidrome.org by default: an instance ID, version, OS and hardware, memory use and basic library and filesystem stats, nothing about the music itself. Set ND_ENABLEINSIGHTSCOLLECTOR=false to stop it; turning off external services also disables it with Last.fm, Deezer and ListenBrainz.
- Last.fm, Deezer and ListenBrainz are the other outside hosts, all used for artwork, artist info and scrobbling. The one bare-IP URL is a TEST-NET address in a plugin test.
- Of 136 known advisories, 119 are in ui/package-lock.json, the web player's build tooling (brace-expansion, babel, browserslist), which is compiled into static files rather than shipped as packages. The Go server's go.mod has 7 (1 moderate, 6 unrated).
- 6 workflows, none using pull_request_target; none of the 11 third-party actions is pinned to a commit. Dependabot, licence, contributing guide and code of conduct present; no security policy or CodeQL. OpenSSF Scorecard 4.9.
What the scanner counted
| Check | Result |
|---|---|
| Secrets | None found. |
| Suspicious code | 1 pattern hit found and read; every one is listed under the raw findings. |
| Install-time code | 1 npm lifecycle script. 1 installer script |
| Committed binaries | None. |
| CI workflows | 6 workflows. None use pull_request_target. 11 of 11 third-party actions pinned to a tag rather than a commit. |
| Network hosts | 40 distinct hosts referenced from source; most often github.com, auth.deezer.com, www.last.fm, api.deezer.com. 1 URL to a bare IP address, listed under the raw findings. |
| Known vulnerabilities | 136 advisories across 1,127 pinned packages: 0 critical, 52 high, 49 moderate, 18 low, 17 unrated. go.mod: 135 packages, 7 advisories; plugins/cmd/ndpgen/go.mod: 17 packages, 10 advisories; plugins/examples/crypto-ticker/go.mod: 7 packages, 0 advisories; plugins/examples/minimal/go.mod: 7 packages, 0 advisories; plugins/examples/wikimedia/go.mod: 7 packages, 0 advisories; plugins/pdk/go/go.mod: 6 packages, 0 advisories; plugins/pdk/rust/nd-pdk-host/Cargo.lock: 41 packages, 1 advisories; plugins/testdata/partial-metadata-agent/go.mod: 7 packages, 0 advisories; plugins/testdata/test-artwork/go.mod: 7 packages, 0 advisories; plugins/testdata/test-cache-plugin/go.mod: 7 packages, 0 advisories; plugins/testdata/test-config/go.mod: 7 packages, 0 advisories; plugins/testdata/test-kvstore/go.mod: 7 packages, 0 advisories; plugins/testdata/test-library/go.mod: 7 packages, 0 advisories; plugins/testdata/test-lyrics/go.mod: 7 packages, 0 advisories; plugins/testdata/test-matcher/go.mod: 7 packages, 0 advisories; plugins/testdata/test-metadata-agent/go.mod: 7 packages, 0 advisories; plugins/testdata/test-scheduler/go.mod: 7 packages, 0 advisories; plugins/testdata/test-scrobble-retriever/go.mod: 7 packages, 0 advisories; plugins/testdata/test-scrobbler/go.mod: 7 packages, 0 advisories; plugins/testdata/test-sonic-similarity/go.mod: 7 packages, 0 advisories; plugins/testdata/test-storage-plugin/go.mod: 7 packages, 0 advisories; plugins/testdata/test-subsonicapi-plugin/go.mod: 7 packages, 0 advisories; plugins/testdata/test-taskqueue/go.mod: 7 packages, 0 advisories; plugins/testdata/test-users/go.mod: 7 packages, 0 advisories; plugins/testdata/test-websocket/go.mod: 7 packages, 0 advisories; ui/package-lock.json: 992 packages, 118 advisories. |
| Project hygiene | Has automated dependency updates, licence file, contributing guide. Missing security policy, CodeQL. |
| OpenSSF Scorecard | 4.9 out of 10, as of Oct 19, 2026. |
The raw findings
Every hit the scanner wrote out, with a link to the exact line at the scanned commit. Secrets candidates are redacted.
Pattern hits (1)
| Where | Rule | Match |
|---|---|---|
| Makefile:95 | download-piped-to-shell | curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s $(GOLANGCI_LINT_VERSION); \ |
URLs to bare IP addresses (1)
| Where | Rule | Match |
|---|---|---|
| plugins/host_httpclient_test.go:141 | ip-literal-url | URL: "http://203.0.113.1:1/test", // TEST-NET-3, non-routable but not private |
npm lifecycle scripts (1)
ui/package.jsonpostinstall:bin/update-workbox.sh
Installer scripts (1)
- scripts/setup-worktree.sh, 58 lines
Worst known vulnerabilities (24 of 136)
| Advisory | Severity | Package | Summary |
|---|---|---|---|
| GHSA-fv7c-fp4j-7gwp | high | @babel/plugin-transform-modules-systemjs@7.29.0 | @babel/plugin-transform-modules-systemjs generates arbitrary code when compiling malicious input |
| GHSA-3jxr-9vmj-r5cp | high | brace-expansion@1.1.13 | brace-expansion: DoS via exponential-time expansion of consecutive non-expanding {} groups |
| GHSA-6j4f-fj2g-mc7p | high | brace-expansion@1.1.13 | brace-expansion: DoS via uncontrolled recursion in parseCommaParts causing stack exhaustion |
| GHSA-mh99-v99m-4gvg | high | brace-expansion@1.1.13 | brace-expansion: DoS via unbounded expansion length causing an out-of-memory process crash |
| GHSA-qhr7-859c-m2p7 | high | brace-expansion@1.1.13 | brace-expansion: DoS via uncontrolled recursion on nested brace groups causing stack exhaustion |
| GHSA-rgw5-rvv9-x895 | high | brace-expansion@1.1.13 | brace-expansion: DoS via unbounded intermediate arrays, bypassing the CVE-2026-14257 mitigation |
| GHSA-3jxr-9vmj-r5cp | high | brace-expansion@2.0.3 | brace-expansion: DoS via exponential-time expansion of consecutive non-expanding {} groups |
| GHSA-6j4f-fj2g-mc7p | high | brace-expansion@2.0.3 | brace-expansion: DoS via uncontrolled recursion in parseCommaParts causing stack exhaustion |
| GHSA-mh99-v99m-4gvg | high | brace-expansion@2.0.3 | brace-expansion: DoS via unbounded expansion length causing an out-of-memory process crash |
| GHSA-qhr7-859c-m2p7 | high | brace-expansion@2.0.3 | brace-expansion: DoS via uncontrolled recursion on nested brace groups causing stack exhaustion |
| GHSA-rgw5-rvv9-x895 | high | brace-expansion@2.0.3 | brace-expansion: DoS via unbounded intermediate arrays, bypassing the CVE-2026-14257 mitigation |
| GHSA-73wf-gq98-2v4g | high | browserslist@4.28.2 | Browserslist: Uncaught crash / prototype write via untrusted browserslist-stats.json custom stats (normalizeStats) |
| GHSA-c83g-rgw3-j3cx | high | browserslist@4.28.2 | Browserslist: Unbounded memory growth (no cache eviction) via distinct query results, leading to eventual OOM |
| GHSA-mrv2-3pqr-j5jr | high | dompurify@3.3.3 | DOMPurify IN_PLACE: hook that removes a parent or sibling leaves the detached subtree's event handlers armed (incomplete… |
| GHSA-4c8g-83qw-93j6 | high | fast-uri@3.1.0 | fast-uri vulnerable to host confusion via failed IDN canonicalization |
| GHSA-7p8r-x3mc-p8w7 | high | fast-uri@3.1.0 | fast-uri vulnerable to host confusion via backslash authority introducer |
| GHSA-f65p-4m7j-42xc | high | fast-uri@3.1.0 | fast-uri vulnerable to server-side request forgery via malformed IPv6 normalization |
| GHSA-jqff-g426-hqxp | high | fast-uri@3.1.0 | fast-uri vulnerable to host confusion via percent-encoded scheme normalization |
| GHSA-q3j6-qgpj-74h6 | high | fast-uri@3.1.0 | fast-uri vulnerable to path traversal via percent-encoded dot segments |
| GHSA-qw65-cvwx-89v3 | high | fast-uri@3.1.0 | fast-uri vulnerable to authority injection via an unvalidated port in serialize |
| GHSA-v2hh-gcrm-f6hx | high | fast-uri@3.1.0 | fast-uri vulnerable to host confusion via literal backslash authority delimiter |
| GHSA-v39h-62p7-jpjc | high | fast-uri@3.1.0 | fast-uri vulnerable to host confusion via percent-encoded authority delimiters |
| GHSA-834v-8h66-3h79 | high | happy-dom@20.8.9 | Happy DOM: Incomplete fix for CVE-2026-33943: unsanitized import alias leads to host code execution |
| GHSA-v56q-mh7h-f735 | high | immutable@4.3.8 | Immutable.js `List` 32-bit trie overflow → unrecoverable DoS |
By the numbers
| Stars | 24.4K |
|---|---|
| Forks | 1,776 |
| Contributors | 267 |
| Commits | 5,194 |
| Open issues | 139 |
| Open pull requests | 201 |
| Releases | 121 |
| Latest release | v0.64.2 |
| Licence | GPL-3.0 |
| Main language | Go |
| Project age | 10 years |
| Last push | Oct 26, 2026 |
| Tracked files | 2,246 |
| Lines of code | 323.1K |
| Checkout size | 20 MB |
Lines by language: Go 226.5K, JavaScript 47.9K, JSON 30.2K, Rust 6,941, Markdown 4,443, YAML 3,879.
Questions
Is Navidrome free?
Yes. Navidrome is free and open source under GPL-3.0. You run it on your own hardware at no cost. Some cloud hosts offer managed Navidrome for a fee and share revenue with the project, but nothing requires them.
What apps work with Navidrome?
Any app that speaks the Subsonic API, which covers dozens of players on iOS, Android and desktop. Navidrome also has its own web player that works on phones through the browser.
Can Navidrome run on a Raspberry Pi?
Yes. It has ready-made binaries and Docker images for Raspberry Pi and uses very little memory, so a Pi with a USB drive full of music is a common setup.
This post is part of GitHub Tools, where every repository is cloned and scanned before it is written up. The scan is a snapshot of one commit on one day; the repository has moved on since, so check it before you install.
