Skip to content

Plugin Architecture


The Stream Deck application loads all the custom plugins it finds when it is started. A set of APIs allows a bidirectional communication between the plugins and the Stream Deck application. This communication is implemented using WebSockets and the messages are exchanged as json data:

Each plugin communicates with the Stream Deck application using a dedicated websocket on a port specified by the Stream Deck application. In order to communicate through this websocket, the plugin has to follow a Registration Procedure.

There is a single instance of the plugin running in the Stream Deck application, even if there are multiple keys using some actions provided by the plugin. Once registered, the plugin will be able to receive and send events like the keyDown and keyUp events.

With the Stream Deck SDK, you can write cross-platform plugins in Javascript. The SDK also supports native compiled code (C++, Objective-C, ...) if you prefer.


A plugin is a container on disk which has all the informations to describe one or more actions through a json manifest, images and code. These files are not supposed to be edited by the users. A plugin is composed of 4 elements:

  • Manifest: Describe the plugin (name, author, icon, ..) and define the actions
  • Code: The code that is executed, for example when a key is pressed
  • Property Inspector: The UI displayed in the property inspector of the actions
  • Various assets (images, localization, ...)

The manifest file has a CodePath member indicating the path to the plugin's code. This could be an HTML file (in case you use Javascript) or the path to a compiled command line tool (C++, Objective-C, ...). In both cases the plugin is loaded as a separate process.

Plugin Unique Identifier

Each plugin has a unique identifier which is used to identify the plugin in the Stream Deck store. The unique identifier must be a uniform type identifier (UTI) that contains only lowercase alphanumeric characters (a-z, 0-9), hyphen (-), and period (.). The string must be in reverse-DNS format. For example, if your domain is and you create a plugin named Hello, you could assign the string com.elgato.hello as your plugin's Unique Identifier.

Plugin Instance

Each plugin has a single instance. If you drag an action ten times onto Stream Deck at 10 different key locations, a keypress or release at these locations will be sent to that single instance, with 10 different contexts.


A plugin can describe multiple actions in its manifest.

For example the Game Capture plugin has 6 actions: Scene, Record, Screenshot, Flashback Recording, Stream, Live Commentary. All of these actions are described in the manifest.json file:

  • actions name
  • actions icons in the actions list in Stream Deck
  • default images
  • ...

Actions instances and coordinates

An action can be instantiated at any location on Stream Deck. Some events are accompanied by the coordinates of the instance which sent the event. The coordinate system is zero-based:

Each instance of the action has an opaque context which is used internally by the Stream Deck application to locate the instance.


The user can have multiple instances of an action. For example he can have one instance of the action at the coordinate [1,1] and one instance of the action at the coordinate [2,2]. Each instance of the action has an opaque context. You shouldn't rely on this value. It is used internally by the Stream Deck application to identify the action's instance. This opaque value needs to be passed to various APIs.

Communication between the plugin and Property Inspector

The plugin and the Property Inspector are running independently from each other. Both should register to the Stream Deck application using the Registration Procedure and can communicate with the Stream Deck application using a dedicated websocket.

There are several APIs available to exchange data between the plugin and the Property Inspector:

  • When the Property Inspector is displayed, the current settings of the selected action are passed directly to the Property Inspector in the inActionInfo parameter. The Property Inspector can use this information to display the current settings in its UI.

  • When the settings are modified in the Property Inspector, the Property Inspector can use the setSettings API to persistently saved the settings for the action's instance. The plugin will also automatically receive a didReceiveSettings callback with the new settings.

  • If you need to save some data globally for the plugin, like for example a token to access a third party service, you can use the setGlobalSettings API. The data will be saved per plugin securely. Note that when the plugin uses setGlobalSettings, the Property Inspector will automatically receive a didReceiveGlobalSettings callback with the new global settings. Similarly when the Property Inspector uses this API, the plugin will automatically receive a didReceiveGlobalSettings callback.

  • If you need to pass internal data from the plugin to the Property Inspector, you can use the sendToPropertyInspector API.

  • Similarly if you need to pass internal data from the Property Inspector to the plugin, you can use the sendToPlugin API.