v0.60.0
Plugins
This release introduces a major rewrite of the experimental Plugin System, now with multi-language PDK support, enabling developers to extend Navidrome's functionality using WebAssembly-based plugins written in Go, Rust, Python or JavaScript. Plugins run in a secure sandbox and can provide additional metadata sources, custom integrations, and server-side enhancements. Users can now easily configure plugins directly from the UI through a new JSONForms-based configuration interface.
A couple of working plugins are already available:
For more plugins, keep an eye on the tag navidrome-plugins in GitHub.
More details and instructions on how to use and manage plugins can be found in our documentation. New documentation will soon be added with details on how to create new plugins.
Metadata Extraction
Additionally, this version includes a pure-Go metadata extractor built on top of the new go-taglib library. This is a significant step toward removing the C++ TagLib dependency, which will simplify cross-platform builds and packaging in future releases. The new extractor is activated by default, but in case of any issues you can revert to the previous implementation by setting Scanner.Extractor="legacy-taglib" configuration option.
Instant Mix
The Instant Mix feature generates a playlist of similar songs based on a selected track. By default, it retrieves similar songs from Last.fm (if configured with an API key) or falls back to Deezer. It can also be configured to use external plugins, like AudioMuse-AI for sonic analysis-based similarity recommendations.
New and Changed Configuration Options
Plugin System Options
| Option | Default | Description |
|----------------------|-----------|---------------------------------------------------------------|
| Plugins.Enabled | true | Enable/disable the plugin system |
| Plugins.Folder | "" | Path to the plugins directory. Default: $DataFolder/Plugins |
| Plugins.CacheSize | "200MB" | Maximum cache size for storing compiled plugin WASM modules |
| Plugins.AutoReload | false | Automatically detect new/changed/removed plugins |
| Plugins.LogLevel | "" | Override log level for plugin-related messages |
Subsonic API Options
| Option | Default | Description |
|--------------------------------|---------|--------------------------------------------------------------------------------------------------------------------------------|
| Subsonic.MinimalClients | "" | Comma-separated list of clients that receive reduced API responses (useful for resource-constrained devices like smartwatches) |
| Subsonic.EnableAverageRating | true | Include average rating in API responses |
Metadata & Matching Options
| Option | Default | Description |
|------------------------------|---------|----------------------------------------------------------------------------------------------------|
| SimilarSongsMatchThreshold | 85 | Minimum similarity score (0-100) for matching similar songs from external sources to local library |
| LastFM.Language | "en" | Now supports comma-separated list of languages (e.g., "de,fr,en") for metadata fallback |
| Deezer.Language | "en" | Now supports comma-separated list of languages for metadata fallback |
Renamed Options (Deprecation Notice)
The following options have been renamed. The old names still work but will be removed in a future release:
| Old Name | New Name |
|-----------------------------------------------|----------------------------|
| HTTPSecurityHeaders.CustomFrameOptionsValue | HTTPHeaders.FrameOptions |
Security
- Fix potential XSS vulnerability by sanitizing user-supplied data before rendering (GHSA-rh3r-8pxm-hg4w). (d7ec735 by @AlexGustafsson)
- Fix potential DoS vulnerability in cover art upscaling by clamping requested square size to original dimensions (GHSA-hrr4-3wgr-68x3). (77367548 by @deluan). Thanks to @yunfachi
Added
-
Plugins:
-
Server:
- Add pure-Go metadata extractor (
go-taglib) as alternative to FFmpeg-based extraction. (#4902 by @deluan) - Add support for reading embedded images using the new taglib extractor by default. (66474fc by @deluan)
- Add Instant Mix (song-based Similar Songs) functionality with MBID, ISRC and Title/Artist fuzzy matching. (#4919, #4946 by @deluan)
- Add support for multiple languages when fetching metadata from Last.fm and Deezer. (#4952 by @deluan)
- Add
Subsonic.MinimalClientsconfiguration option for improved compatibility with minimal Subsonic clients. Default list is"SubMusic"(#4850 by @typhoon2099) - Add support for public/private playlists in NSP import. (c5447a6 by @deluan)
- Add RISCV64 builds. (#4949 by @MichaIng)
- Add pure-Go metadata extractor (
-
UI Features:
- Add composer field to table views. (#4857 by @AlexGustafsson)
- Add prompt before closing window if music is playing. (#4899 by @alannnna)
- Add Nautiline-like theme. (#4909 by @borisrorsvort)
- Add multiline support and resizing for playlist comment input. (6fce30c by @deluan)
-
Subsonic API:
-
Insights:
Changed
- Optimize cross-library move detection for single-library setups. (#4888 by @deluan)
- Improve Deezer artist search ranking. (a081569 by @deluan)
- Rename
HTTPSecurityHeaders.CustomFrameOptionsValuetoHTTPHeaders.FrameOptions. (7ccf44b by @deluan) - Update translations: Bulgarian, Catalan, German, Greek, Spanish, Finnish, French, Galician, Indonesian, Dutch, Polish, Russian, Slovenian, Swedish, Thai by POEditor contributors.
- Update Spanish translations. (#4904 by @abrugues)
- Update Basque translation. (#4815 by @xabirequejo)
Fixed
-
Playlists:
-
UI:
- Fix various UI issues and improve styling coherence. (#4910 by @borisrorsvort)
- Fix AMusic theme player buttons and delete button color. (#4797 by @dragonish)
- Fix export missing files showing only first 1000 results. (017676c by @deluan)
-
Scanner:
- Fix
FullScanInProgressnot reflecting current scan request during interrupted scans. (8c80be5 by @deluan) - Fix "Expression tree is too large" error by executing GetFolderUpdateInfo in batches. (cde5992 by @deluan)
- Fix stale role associations when artist role changes. (2d7b716 by @deluan)
- Fix infinite recursion in PID configuration. (1c4a7e8 by @deluan)
- Fix default PIDs not being set for Album and Track. In some circumstances it could lead to empty PIDs (71f549a by )
- Fix
-
Subsonic API:
-
Server:
- Fix JWT-related errors being exposed on share page. (#4892 by @AlexGustafsson)
- Fix user context not preserved in async NowPlaying dispatch. (396eee4 by @deluan)
- Fix environment variable configuration loading not being logged when no config file is found. (51ca2de by @deluan)
- Fix items with no annotation not being included for
starred=falsefilter, handlehas_rating=false. (#4921 by @kgarner7) - Last.fm's
scrobbleandupdateNowPlayingmethods should send parameters in request body. (51026de by )
New Contributors
- @alannnna made their first contribution in #4899
- @abrugues made their first contribution in #4904
- @AlexGustafsson made their first contribution in #4857
- @borisrorsvort made their first contribution in #4909
- @dragonish made their first contribution in #4797
- @MichaIng made their first contribution in #4949
- @terry90 made their first contribution in #4900
- @typhoon2099 made their first contribution in #4850
Full Changelog: https://github.com/navidrome/navidrome/compare/v0.59.0...v0.60.0
Helping out
This release is only possible thanks to the support of some awesome people!
Want to be one of them? You can sponsor, pay me a Ko-fi, or contribute with code.