Plugin SDK for Nuclear music player
npm install @nuclearplayer/plugin-sdkBuild plugins for Nuclear music player.
Plugins are JavaScript/TypeScript modules that extend Nuclear's functionality. Write lifecycle hooks, register providers, and ship it as an npm package or local bundle.
``bash`
mkdir my-plugin && cd my-plugin
pnpm init -y
pnpm add @nuclearplayer/plugin-sdk
Create src/index.ts:
`ts
import { NuclearPluginAPI } from '@nuclearplayer/plugin-sdk';
export default {
async onLoad(api: NuclearPluginAPI) {
console.log('Plugin loaded');
},
async onEnable(api: NuclearPluginAPI) {
console.log('Plugin enabled');
},
async onDisable() {
console.log('Plugin disabled');
},
async onUnload() {
console.log('Plugin unloaded');
},
};
`
Build it to dist/index.js as a CommonJS bundle.
- Unique plugin ID (scoped names allowed)
- version - Semver version
- description - One-line summary
- author - Your name$3
- main - Entry file path (defaults to index.js or dist/index.js)$3
Add a nuclear object for extra metadata:-
displayName - Friendly name (defaults to name)
- category - Arbitrary grouping (e.g., source, integration, lyrics)
- icon - See below
- permissions - Capabilities your plugin uses (informational only for now)`json
{
"name": "@nuclear-plugin/lastfm",
"version": "0.1.0",
"description": "Scrobble tracks to Last.fm",
"author": "Nuclear Team",
"main": "dist/index.js",
"nuclear": {
"displayName": "Last.fm Scrobbler",
"category": "integration",
"icon": { "type": "link", "link": "https://example.com/icon.png" },
"permissions": ["scrobble", "network"]
}
}
`Icons
`ts
type PluginIcon = { type: 'link'; link: string };
`Link icons should point to a local file path or remote URL; keep them small (<= 64x64, optimized).
Lifecycle Hooks
All hooks are optional. Export a default object with any of:
-
onLoad(api) - Runs after plugin code loads and manifest is parsed
- onEnable(api) - Runs when user enables the plugin
- onDisable() - Runs when user disables it
- onUnload() - Runs before plugin is removed from memory`ts
export default {
async onLoad(api) {
},
async onEnable(api) {
},
async onDisable() {
},
async onUnload() {
},
};
`Permissions
Declare what your plugin does in the
permissions array. Permissions are currently informational. Future versions might show UI for this.Examples:
network, scrobble, playback-control, lyrics, search, storageFile Structure
`text
my-plugin/
package.json
src/
index.ts
dist/
index.js
`Building
You can use any bundler that outputs a single JS file. Your bundle needs to work in a CommonJS environment (
module.exports or exports.default).Example with tsup:
`json
{
"devDependencies": { "tsup": "^8" },
"scripts": { "build": "tsup src/index.ts --dts --format cjs --minify --out-dir dist" }
}
`Run
pnpm build and you'll get dist/index.js.Development
1. Create your plugin folder
2. Build to produce the entry file
3. Load it in Nuclear
4. Rebuild after changes; you'll need to reload the plugin
Tips
- Keep startup fast, defer heavy work to
onEnable
- Validate network responses
- Minimize dependencies, smaller = fasterTroubleshooting
| Problem | Solution |
|---------|----------|
| Can't find entry file | Check
main in package.json or make sure index.js or dist/index.js exists |
| Missing fields error | Add all required fields: name, version, description, author |
| Hooks don't fire | Export a default object, not a function or class |Types
`ts
import type {
NuclearPlugin,
PluginManifest,
PluginIcon,
// Model types (re-exported from @nuclearplayer/model)
Artist,
Album,
Track,
// ... and many more
} from '@nuclearplayer/plugin-sdk';
``AGPL-3.0-only