# Navidrome Plugin ExamplesThis folder contains example plugins demonstrating various capabilities and languages supported by Navidrome's plugin system.## Available Examples| Plugin | Language | Capabilities | Description ||-------------------------------------------------------|----------|-------------------------------------------------|--------------------------------|| [minimal](minimal/) | Go | MetadataAgent | Basic plugin structure || [wikimedia](wikimedia/) | Go | MetadataAgent | Wikidata/Wikipedia metadata || [crypto-ticker](crypto-ticker/) | Go | Scheduler, WebSocket, Cache | Real-time crypto prices (demo) || [coverartarchive-py](coverartarchive-py/) | Python | MetadataAgent | Cover Art Archive || [nowplaying-py](nowplaying-py/) | Python | Scheduler, SubsonicAPI | Now playing logger || [webhook-rs](webhook-rs/) | Rust | Scrobbler | HTTP webhook on scrobble || [library-inspector-rs](library-inspector-rs/) | Rust | Library, Scheduler | Periodic library stats logging || [discord-rich-presence-rs](discord-rich-presence-rs/) | Rust | Scrobbler, Scheduler, WebSocket, Cache, Artwork | Discord integration (Rust) |## Building### Prerequisites- **Go plugins:** [TinyGo](https://tinygo.org/getting-started/install/) 0.30+- **Python plugins:** [extism-py](https://github.com/extism/python-pdk)- **Rust plugins:** [Rust](https://rustup.rs/) with `wasm32-unknown-unknown` target### Build All Plugins```bashmake all```This creates `.ndp` package files for each plugin.### Build Individual Plugin```bashmake minimal.ndpmake wikimedia.ndpmake discord-rich-presence-rs.ndp```### Clean```bashmake clean```## Testing Plugins### With Extism CLITest any plugin without running Navidrome. First extract the `.wasm` file from the `.ndp` package:```bash# Install: https://extism.org/docs/install# Extract the wasm file from the packageunzip -p minimal.ndp plugin.wasm > minimal.wasm# Test a capability functionextism call minimal.wasm nd_get_artist_biography --wasi \--input '{"id":"1","name":"The Beatles"}'```For plugins that make HTTP requests, allow the hosts:```bashunzip -p wikimedia.ndp plugin.wasm > wikimedia.wasmextism call wikimedia.wasm nd_get_artist_biography --wasi \--input '{"id":"1","name":"Yussef Dayes"}' \--allow-host "query.wikidata.org" \--allow-host "en.wikipedia.org"```### With Navidrome1. Copy the `.ndp` file to your plugins folder2. Enable plugins in `navidrome.toml`:```toml[Plugins]Enabled = trueFolder = "/path/to/plugins"```3. For metadata agents, add to your agents list:```tomlAgents = "lastfm,spotify,wikimedia"```## Creating Your Own Plugin### Option 1: Start from MinimalCopy the [minimal](minimal/) example and modify:```bashcp -r minimal my-plugincd my-plugin# Edit main.go and manifest.jsontinygo build -o plugin.wasm -target wasip1 -buildmode=c-shared .zip -j my-plugin.ndp manifest.json plugin.wasm```### Option 2: Bootstrap with XTP CLIGenerate boilerplate from a schema:```bash# Install XTP: https://docs.xtp.dylibso.com/docs/clixtp plugin init \--schema-file ../schemas/metadata_agent.yaml \--template go \--path ./my-plugin \--name my-plugin# Then create manifest.json and packagecd my-pluginxtp plugin buildzip -j my-plugin.ndp manifest.json dist/plugin.wasm```Available schemas in [../schemas/](../schemas/):- `metadata_agent.yaml` – Artist/album metadata- `scrobbler.yaml` – Scrobbling integration- `lifecycle.yaml` – Init callbacks- `scheduler_callback.yaml` – Scheduled tasks- `websocket_callback.yaml` – WebSocket events### Option 3: Different LanguageSee language-specific examples:- **Python:** [coverartarchive-py](coverartarchive-py/)- **Rust:** [webhook-rs](webhook-rs/)## Example Breakdown### Minimal (Go)The simplest possible plugin. Shows:- Manifest export- Single capability function- Basic input/output handling### Wikimedia (Go)Real-world metadata agent. Shows:- HTTP requests to external APIs- SPARQL queries (Wikidata)- Error handling- Host allowlisting### Discord Rich Presence (Go)Complex multi-capability plugin. Shows:- **Scrobbler** – Receives play events- **WebSocket** – Maintains Discord gateway connection- **Scheduler** – Heartbeat and timeout management- **Cache** – Connection state storage- **Artwork** – Getting album art URLs### Cover Art Archive (Python)Python metadata agent. Shows:- extism-py plugin structure- HTTP requests- JSON handling### Webhook (Rust)Rust scrobbler. Shows:- extism-rs plugin structure- HTTP POST requests- Minimal dependencies## Resources- [Plugin System Documentation](../README.md)- [Extism PDK Docs](https://extism.org/docs/concepts/pdk)- [TinyGo WebAssembly](https://tinygo.org/docs/guides/webassembly/)- [XTP CLI](https://docs.xtp.dylibso.com/docs/cli)