writing-plugins
// Use when writing, scaffolding, or modifying Nuclear plugins. Covers plugin structure, manifest, entry point, provider types, available APIs, and publishing. Trigger phrases include "create a plugin", "write a plugin", "plugin scaffold", "streaming provider", "metadata provider".
$ git log --oneline --stat
stars:17,016
forks:3.2k
updated:March 4, 2026
SKILL.mdreadonly
SKILL.md Frontmatter
namewriting-plugins
descriptionUse when writing, scaffolding, or modifying Nuclear plugins. Covers plugin structure, manifest, entry point, provider types, available APIs, and publishing. Trigger phrases include "create a plugin", "write a plugin", "plugin scaffold", "streaming provider", "metadata provider".
Writing Nuclear Plugins
Plugins are standalone repos compiled in-browser via esbuild-wasm.
Structure
my-plugin/
package.json # Manifest with nuclear metadata
src/
index.ts # Entry point, default exports NuclearPlugin
Manifest (package.json)
{
"name": "nuclear-plugin-example",
"version": "0.1.0",
"description": "What this plugin does",
"author": "Your Name",
"license": "AGPL-3.0-only",
"main": "src/index.ts",
"type": "module",
"nuclear": {
"displayName": "Example Plugin",
"category": "streaming",
"icon": { "type": "link", "link": "https://example.com/icon.svg" }
},
"dependencies": {
"@nuclearplayer/plugin-sdk": "^1.1.0"
}
}
Categories: streaming, metadata, lyrics
Entry Point
import type { NuclearPlugin, NuclearPluginAPI } from '@nuclearplayer/plugin-sdk';
const plugin: NuclearPlugin = {
onLoad(api: NuclearPluginAPI) {},
onEnable(api: NuclearPluginAPI) {
// Register providers
},
onDisable() {
// Unregister providers
},
onUnload() {},
};
export default plugin;
Provider Types
Streaming - resolve tracks to playable audio:
const provider: StreamingProvider = {
id: 'my-streaming',
kind: 'streaming',
name: 'My Streaming',
async searchForTrack(artist, title, album?) { /* return StreamCandidate[] */ },
async getStreamUrl(candidateId) { /* return Stream */ },
};
api.Providers.register(provider);
api.Providers.unregister('my-streaming');
Metadata - search artists/albums, fetch details:
const provider: MetadataProvider = {
id: 'my-metadata',
kind: 'metadata',
name: 'My Metadata',
searchCapabilities: ['artists', 'albums'],
streamingProviderId: 'my-streaming', // Optional: locks streaming to this provider
async searchArtists(params) { /* ... */ },
async searchAlbums(params) { /* ... */ },
async fetchArtistBio(id) { /* ... */ },
async fetchAlbumDetails(id) { /* ... */ },
};
Available APIs
api.Providers- register/unregister providersapi.Settings- plugin settings storageapi.Http- fetch wrapperapi.Ytdlp- yt-dlp integrationapi.Queue- playback queue controlapi.Metadata- search music metadataapi.Streaming- resolve streamsapi.Logger- logging (trace/debug/info/warn/error)
Publishing
- Create a GitHub repo with the plugin code
- Add
.github/workflows/release.yml:
name: Release
on:
push:
tags: ['v*']
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- run: zip -r plugin.zip src package.json README.md
- uses: softprops/action-gh-release@v2
with:
files: plugin.zip
generate_release_notes: true
- Tag release:
git tag v0.1.0 && git push --tags - Submit PR to
NuclearPlayer/plugin-registryadding your plugin toplugins.json