Welcome to the Stream Deck SDK for Node.js. Designed to make creating Stream Deck plugins easy, the Stream Deck SDK provides everything you need to connect, communicate and build with Stream Deck, and lets you focus on the fun stuff.
The Stream Deck SDK for Node.js is currently in public beta, and is available to everyone running Stream Deck 6.4 or newer. If you're interested in building plugins and would like to know more, please join our Marketplace Makers Discord.
Creating Stream Deck plugins with Node.js requires Node.js v20.5.1. When installing Node.js, we recommended using a version manager such as nvm (macOS) or nvm-windows (Windows).
We recommend using the @elgato/cli
tool for building Stream Deck plugins as this provides all scaffolding required to get started with a sample "Counter" plugin.
Install the CLI.
npm install -g @elgato/cli
Once installed, run the create
command to initialize the creation wizard.
streamdeck create
After creating a plugin with streamdeck create
you'll be provided with a local environment for building a plugin.
/
βββ *.sdPlugin/
β βββ bin/
β βββ imgs/
β βββ logs/
β βββ manifest.json
βββ src/
β βββ actions/
β β βββ increment-counter.ts
β βββ plugin.ts
βββ package.json
βββ rollup.config.mjs
βββ tsconfig.json
The root of the plugin; this folder contains the build output from the source files as well as assets that support the plugin, such as icons, profiles, etc.
- manifest.json - plugin metadata (for more information, see manifest documentation).
- bin/ - build output.
- imgs/ - assets used by the plugin, such as icons, profiles, etc.
- logs/ - logs generated from
streamDeck.logger
.
- plugin.ts - build entry point.
- actions/increment-counter.ts - example "Counter" action.
The package.json
provides two scripts for building the plugin.
npm run build
- builds the plugin.npm run watch
- continuously watches for changes, and hot-reloads the plugin after build.
Actions are the star of the show and enable users to interact with plugins. At their core, actions are classes that fulfil an interface. This enables the SDK to route events, such as key down, dial rotate, etc., emitted from Stream Deck to the appropriate action, as determined by the action's unique-identifier.
The following is an example of an action that listens for the keyDown
event, and then sets the title of the action to "Hello world" after being pressed.
src/actions/say-hello.ts
import { action, KeyDownEvent, SingletonAction } from "@elgato/streamdeck"; @action({ UUID: "com.elgato.hello-world.say-hello" }) export class SayHelloAction extends SingletonAction { /** * Listen for the key down event that occurs when a user presses * a Stream Deck button, and change the title of the action. */ async onKeyDown(ev: KeyDownEvent<object>) { await ev.action.setTitle("Hello world"); } }
The action's implementation must be registered in the sources' entry point`.
src/plugin.ts
import streamDeck from "@elgato/streamdeck"; import { SayHelloAction } from "./actions/say-hello"; // Register the action, and connect to Stream Deck. streamDeck.actions.registerAction(new SayHelloAction()); streamDeck.connect();
And the action's metadata must be defined within the plugin's manifest file.
*.sdPlugin/manifest.json
{ // Learn more: https://docs.elgato.com/sdk/plugins/manifest "Actions": [ { "Name": "Say Hello", "UUID": "com.elgato.hello-world.say-hello", // Note, this matches the UUID in the action class. "States": [{ "TitleAlignment": "middle" }] } ] }
When observing changes with npm run watch
, the changes will immediately be available within Stream Deck. Altneratively the changes can be built with npm run build
followed by streamdeck restart <uuid>
, where <uuid>
represents the unique-identifier of your plugin.
The streamDeck.devices
collection contains information about known devices associated with the user. This includes information such as the id, name, and type of device. Additionally, as devices may not be connected at all times the Device
provides insight into the connection status of a device.
import streamDeck from "@elgato/streamdeck";
streamDeck.devices.forEach((device) => {
// Device information including id, name, type, etc.
});
Plugins can be debugged from all supporting Node.js debuggers, such as Visual Studio Code, Chrome, etc., and by default will have debugging enabled when created with the CLI tool's streamdeck create
command.
Debugging can be configured from within the plugin's manifest as part the Node.js configuration object.
{
// ...
"Nodejs": {
"Version": "20",
"Debug": "enabled"
}
}
There are four available options when configuring the Debug
property within the manifest:
"enabled"
- the plugin will run with--inspect
allowing debuggers to connect."break"
- the plugin will launch with--inspect-brk
and will await a debugger attaching before running.string
- a collection of CLI arguments supplied to the plugin.undefined
- debugging is disabled.
When running the plugin in either debug mode
"enabled"
or"break"
, a random available port will be allocated to the debug listener each time the plugin launches. If you wish to listen on a specific port, theDebug
value can be set to a string of CLI arguments, for example to listen on port12345
, theDebug
value would be--inspect=127.0.0.1:12345
.
The streamDeck.logger
provides local file-based logging, allowing you to diagnose, track, and debug your plugin. Logs files operate a file-rotation policy and are re-indexed when the plugin starts or the log file exceeds 50MiB, with the 10 most recent log files being retained.
import streamDeck, { LogLevel } from "@elgato/streamdeck";
const logger = streamDeck.logger.createScope("Custom Scope");
logger.error("Error message");
logger.warn("Warning message");
logger.info("Information message");
logger.debug("Debug message"); // β Default level is INFO
logger.trace("Trace message"); // β Default level is INFO
logger.setLevel(LogLevel.TRACE);
logger.debug("Debug message"); // β
logger.trace("Trace message"); // β
When the log-level is set to
TRACE
all communication between the Stream Deck and the plugin will be logged to the file system, this includes all settings. Please ensure sensitive information is not transmitted whilstTRACE
is active.