TypeScript icon, indicating that this package has built-in type declarations

6.0.0 • Public • Published


Node CI codecov

npm version license

@elgato-stream-deck/webhid is a shared library for interfacing with the various models of the Elgato Stream Deck.

Intended use

This library has nothing to do with the streamdeck software produced by Elgato. There is nothing here to install and run. This is a library to help developers make alternatives to that software


$ npm install --save @elgato-stream-deck/webhid


You need to provide a Buffer polyfill to the browser for this library. We recommend using buffer which can be added to your webpack config with:

plugins: [
	new ProvidePlugin({
		Buffer: ['buffer', 'Buffer'],


On linux, the udev subsystem blocks access to the StreamDeck without some special configuration. Save the following to /etc/udev/rules.d/50-elgato.rules and reload the rules with sudo udevadm control --reload-rules

SUBSYSTEM=="input", GROUP="input", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0060", MODE:="666", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0063", MODE:="666", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="006c", MODE:="666", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="006d", MODE:="666", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0080", MODE:="666", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0084", MODE:="666", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0086", MODE:="666", GROUP="plugdev"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0090", MODE:="666", GROUP="plugdev"
KERNEL=="hidraw*", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0060", MODE:="666", GROUP="plugdev"
KERNEL=="hidraw*", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0063", MODE:="666", GROUP="plugdev"
KERNEL=="hidraw*", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="006c", MODE:="666", GROUP="plugdev"
KERNEL=="hidraw*", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="006d", MODE:="666", GROUP="plugdev"
KERNEL=="hidraw*", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0080", MODE:="666", GROUP="plugdev"
KERNEL=="hidraw*", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0084", MODE:="666", GROUP="plugdev"
KERNEL=="hidraw*", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0086", MODE:="666", GROUP="plugdev"
KERNEL=="hidraw*", ATTRS{idVendor}=="0fd9", ATTRS{idProduct}=="0090", MODE:="666", GROUP="plugdev"

Unplug and replug the device and it should be usable


  • Support for every StreamDeck model (Original, Mini & XL)
  • Key down and key up events
  • Fill keys with canvas, images or solid RGB colors
  • Fill the entire panel with a single image, spread across all keys
  • Set the Stream Deck brightness
  • TypeScript support

Known limitations

  • Only works with Chromium v89+ based browsers
  • The original model of the 15key is not supported on linux
  • When having a hid device open, you will still be subject to background tab throttling which affects the draw rate


The root methods exposed by the library are as follows. For more information it is recommended to rely on the typescript typings for hints or to browse through the source to see what methods are available

 * Request the user to select some streamdecks to open
 * @param userOptions Options to customise the device behvaiour
export async function requestStreamDecks(options?: OpenStreamDeckOptions): Promise<StreamDeckWeb[]>

 * Reopen previously selected streamdecks.
 * The browser remembers what the user previously allowed your site to access, and this will open those without the request dialog
 * @param options Options to customise the device behvaiour
export async function getStreamDecks(options?: OpenStreamDeckOptions): Promise<StreamDeckWeb[]>

 * Open a StreamDeck from a manually selected HIDDevice handle
 * @param browserDevice The unopened browser HIDDevice
 * @param userOptions Options to customise the device behvaiour
export async function openDevice(browserDevice: HIDDevice, userOptions?: OpenStreamDeckOptions): Promise<StreamDeckWeb>

The StreamDeck type can be found here


import { requestStreamDecks } from '@elgato-stream-deck/webhid'

// Prompts the user to select a streamdeck to use
const myStreamDecks = await requestStreamDecks()

myStreamDecks[0].on('down', (keyIndex) => {
	console.log('key %d down', keyIndex)

myStreamDecks[0].on('up', (keyIndex) => {
	console.log('key %d up', keyIndex)

// Fired whenever an error is detected by the hid device.
// Always add a listener for this event! If you don't, errors will be silently dropped.
myStreamDecks[0].on('error', (error) => {

// Fill the first button form the left in the first row with a solid red color. This is asynchronous.
await myStreamDecks[0].fillKeyColor(4, 255, 0, 0)
console.log('Successfully wrote a red square to key 4.')

Some the demo site for some more complete examples and its corresponding source.


The elgato-stream-deck team enthusiastically welcomes contributions and project participation! There's a bunch of things you can do if you want to contribute! Please don't hesitate to jump in if you'd like to, or even ask us questions if something isn't clear.

Please refer to the Changelog for project history details, too.

Package Sidebar


npm i @elgato-stream-deck/webhid

Weekly Downloads






Unpacked Size

25.5 kB

Total Files


Last publish


  • julusian