React primitives, hooks, and a custom renderer for building Stream Deck plugins with React across keys, dials, and touch surfaces.
bun add @fcannizzaro/streamdeck-react reactThe fastest way to get started is with the create-streamdeck-react CLI:
bun create streamdeck-react
# or pnpm create streamdeck-react@latest
# or npm create streamdeck-react@latestIt walks you through project setup — name, UUID, package manager, starter example — then optionally installs dependencies and links the plugin to Stream Deck.
Create an action:
import { useState } from "react";
import { defineAction, useKeyDown, tw } from "@fcannizzaro/streamdeck-react";
function CounterKey() {
const [count, setCount] = useState(0);
useKeyDown(() => {
setCount((value) => value + 1);
});
return (
<div
className={tw(
"flex h-full w-full items-center justify-center bg-gradient-to-br from-[#0f766e] to-[#164e63] text-white",
)}
>
<span className="text-[32px] font-bold">{count}</span>
</div>
);
}
export const counterAction = defineAction({
uuid: "com.example.counter",
key: CounterKey,
});Register it in your plugin entrypoint:
import { createPlugin } from "@fcannizzaro/streamdeck-react";
import { counterAction } from "./actions/counter.tsx";
const plugin = createPlugin({
fonts: [],
actions: [counterAction],
});
await plugin.connect();- React-driven rendering for Stream Deck keys, dials, and touch layouts
- Hooks for key, dial, touch, lifecycle, SDK, and settings events
- Optional wrappers for shared providers and external state libraries
- Built-in primitives like
Box,Text,Image,Icon,ProgressBar, andCircularGauge
samples/counter/- local state, settings hook, dial interactionsamples/zustand/- shared external store across multiple actionssamples/jotai/- shared atom state with a plugin-level wrappersamples/pokemon/- richer plugin example with custom wrapperssamples/snake/- snake game on the Stream Deck+ touch strip using dial controls and touch tapsamples/weather/- weather forecast dials with animated detail panels and a shared Zustand store
A browser-based inspector for debugging plugins during development. Enable it in your plugin config:
const plugin = createPlugin({
devtools: true,
// ...
});Then open the hosted UI at streamdeckreact.fcannizzaro.com/devtools, or run a local copy:
npx @fcannizzaro/streamdeck-react-devtoolsPanels include Console, Network, Elements (with on-device highlighting), Preview, and Events. All devtools code is automatically stripped from production builds.
For setup guides, API reference, state-sharing patterns, and more examples, see:
https://streamdeckreact.fcannizzaro.com
MIT
