plugins/examples/README.md
This folder contains example plugins demonstrating various capabilities and languages supported by Navidrome's plugin system.
| Plugin | Language | Capabilities | Description |
|---|---|---|---|
| minimal | Go | MetadataAgent | Basic plugin structure |
| wikimedia | Go | MetadataAgent | Wikidata/Wikipedia metadata |
| crypto-ticker | Go | Scheduler, WebSocket, Cache | Real-time crypto prices (demo) |
| coverartarchive-py | Python | MetadataAgent | Cover Art Archive |
| nowplaying-py | Python | Scheduler, SubsonicAPI | Now playing logger |
| webhook-rs | Rust | Scrobbler | HTTP webhook on scrobble |
| library-inspector-rs | Rust | Library, Scheduler | Periodic library stats logging |
| discord-rich-presence-rs | Rust | Scrobbler, Scheduler, WebSocket, Cache, Artwork | Discord integration (Rust) |
wasm32-unknown-unknown targetmake all
This creates .ndp package files for each plugin.
make minimal.ndp
make wikimedia.ndp
make discord-rich-presence-rs.ndp
make clean
Test any plugin without running Navidrome. First extract the .wasm file from the .ndp package:
# Install: https://extism.org/docs/install
# Extract the wasm file from the package
unzip -p minimal.ndp plugin.wasm > minimal.wasm
# Test a capability function
extism call minimal.wasm nd_get_artist_biography --wasi \
--input '{"id":"1","name":"The Beatles"}'
For plugins that make HTTP requests, allow the hosts:
unzip -p wikimedia.ndp plugin.wasm > wikimedia.wasm
extism call wikimedia.wasm nd_get_artist_biography --wasi \
--input '{"id":"1","name":"Yussef Dayes"}' \
--allow-host "query.wikidata.org" \
--allow-host "en.wikipedia.org"
.ndp file to your plugins foldernavidrome.toml:
[Plugins]
Enabled = true
Folder = "/path/to/plugins"
Agents = "lastfm,spotify,wikimedia"
Copy the minimal example and modify:
cp -r minimal my-plugin
cd my-plugin
# Edit main.go and manifest.json
tinygo build -o plugin.wasm -target wasip1 -buildmode=c-shared .
zip -j my-plugin.ndp manifest.json plugin.wasm
Generate boilerplate from a schema:
# Install XTP: https://docs.xtp.dylibso.com/docs/cli
xtp plugin init \
--schema-file ../schemas/metadata_agent.yaml \
--template go \
--path ./my-plugin \
--name my-plugin
# Then create manifest.json and package
cd my-plugin
xtp plugin build
zip -j my-plugin.ndp manifest.json dist/plugin.wasm
Available schemas in ../schemas/:
metadata_agent.yaml – Artist/album metadatascrobbler.yaml – Scrobbling integrationlifecycle.yaml – Init callbacksscheduler_callback.yaml – Scheduled taskswebsocket_callback.yaml – WebSocket eventsSee language-specific examples:
The simplest possible plugin. Shows:
Real-world metadata agent. Shows:
Complex multi-capability plugin. Shows:
Python metadata agent. Shows:
Rust scrobbler. Shows: