Developer Docs
How to create, publish, and maintain Saltshaker plugins using the public registry and the exposed plugin API.
Quickstart
- Create a plugin repository (your source code lives here).
- Produce a bundled JavaScript entry file (self-contained runtime output).
- Export the required lifecycle hooks (
onInit, optionalonDispose). - Add a per-plugin manifest to the public registry catalog (metadata only).
- Use the registry workflow to bundle and publish a versioned release artifact.
Plugin contract
A Saltshaker plugin is a Node-compatible module that exports lifecycle hooks. Saltshaker will call:
onInit(api)(required): initialize, subscribe, and begin emitting outputsonDispose()(recommended): unsubscribe, remove handlers, and clean up
Your plugin is responsible for deriving:
(1) a stable user identifier (uid) and
(2) a shared room code (roomCode)
so Saltshaker can coordinate peer-to-peer behavior across users.
Runtime API surface
The plugin runtime injects a single object named api into your plugin. The following surfaces are
currently supported.
| API | Description |
|---|---|
api.log(...args) |
Writes plugin-prefixed logs to the client log stream. |
api.sendEvent(name, ...args) |
Emits an outbound plugin event to the platform (e.g. connect, disconnect). |
api.on(name, handler) |
Subscribes to an inbound platform event. Returns a disposer function that removes the handler. |
api.settings.get(key, fallback) |
Reads a plugin setting value (typed at the manifest level). |
api.settings.onChange(handler) |
Receives setting updates for the active plugin (if supported by the runtime). |
api.host.file.readText(resourceId) |
Reads a declared resource as text (permission-gated). |
api.host.file.readJson(resourceId) |
Reads a declared resource as JSON (permission-gated). |
api.host.dolphin.subscribe({ events: [...] }) |
Subscribes to Dolphin events (permission-gated). |
api.host.dolphin.unsubscribe({ events: [...] }) |
Unsubscribes from Dolphin events you previously subscribed to. |
dolphin:GameStartdolphin:GameEnddolphin:Disconnecteddolphin:Error
connect(roomCode, uid)disconnect(roomCode, uid)
Permissions
Permissions are declared in the registry manifest and determine which host capabilities are available at runtime. Request the minimum set needed.
file.read— allows reading declared resources viaapi.host.filedolphin.subscribe— allows subscribing to Dolphin events viaapi.host.dolphin
Resources
Resources are a whitelist of files that Saltshaker will allow your plugin to read. Resources are accessed by ID rather than by filesystem path.
- The registry manifest declares
{ id, path, type }for each resource. - The plugin reads the resource using
api.host.file.readText(resourceId)orreadJson(resourceId). - Plugins should treat resource contents as sensitive user data.
Settings
Settings are declared in the registry manifest so Saltshaker can render configuration UI for users. Plugins read settings at runtime and can optionally react to changes.
- Read setting values during
onInitusingapi.settings.get. - If supported, subscribe to changes using
api.settings.onChange. - Use safe defaults when settings are missing or unreadable.
Publishing via the registry
Saltshaker uses a public plugin registry repository that contains metadata and release artifacts. You publish a plugin by adding or updating the per-plugin manifest in the registry and triggering the bundling workflow.
- Declare plugin metadata:
id,name,description,version,repository,commit,minClientVersion. - Declare required permissions, resources, and settings.
- Do not manually set the artifact URL or SHA-256 hash; those are populated by the bundling workflow.
- Update the catalog index to point “latest” at the new version after publishing.
version as a release contract. If you change emitted event semantics or required permissions,
bump the version and keep changes backwards-aware where possible.
Best practices
- Be deterministic. Emit
connect/disconnectidempotently and avoid oscillation. - Clean up aggressively. Unsubscribe from upstream sources and remove listeners during disposal.
- Keep permissions minimal. Request only what you need for the plugin’s function.
- Avoid collecting data. Only derive what is required to operate (
uid,roomCode). - Fail safe. If required inputs are missing (e.g. no user identifier), suppress connect/disconnect rather than emitting malformed events.
- Provide a clear README for users and maintainers.
- Document what permissions you require and why.
- Keep changes narrowly scoped and testable.