Features & Use Cases
DeckBridge turns a USB Stream Deck into a network device the Elgato app can use over WiFi.
Use a budget deck with the Elgato app
DeckBridge lets the official Elgato Stream Deck app drive cheap, non-Elgato decks —
Mirabox, Ajazz, and similar boards, from 6-key minis to 15-key (3×5) decks. The app sees
a regular Network device at localhost; the deck behaves like Elgato hardware.
Feature overview
- Network Dock emulation — Elgato CORA protocol over TCP, advertised via mDNS
_elg._tcp("Network Stream Deck"); the app discovers it like real hardware. - Works with non-Elgato decks — supported Mirabox / Ajazz decks present themselves to the app as an Elgato model it already knows, so nothing changes app-side.
- Multiple decks (distinct models) — extra connected decks of a different model each appear as their own network dock, with per-deck pairing cards, a selectable live preview, and per-deck brightness in the web UI; see Multiple decks for the walkthrough and Limitations for the rules and caveats.
- Per-device image pipeline — resizes, rotates, and (for the K1 Pro) re-encodes every button image to the device's native format via a Rust native library, with a cache to skip repeat work.
- Non-blocking by design — USB HID and the 50–200 ms image transforms run on a separate worker thread, so the network ACK loop and web UI never stall.
- Side-key widgets — decks with display-only keys outside the grid (e.g. the 293S sixth column) show server-rendered clock / date / text / weather / command / plugin widgets; see Side-key widgets.
- Live web UI —
http://localhost:3000shows the key grid and a log feed in real time. - System tray + diagnostics — packaged releases (installers and release zips) include
a status tray icon (states) and a
/requirementsself-check page. - Standalone binary — one <5 MB file built on txiki.js; no Node.js.
Use cases
- Put the deck on another computer — plug the deck into a laptop or mini-PC, run DeckBridge there, and control the Elgato app on your streaming PC across the LAN.
- Skip the Network Dock — network-dock behaviour for hobby setups without buying the hardware.
- Use a real Stream Deck wirelessly — a Stream Deck Mini or MK.2 works the same way, over WiFi instead of a cable.
- Bitfocus Companion — Companion also speaks the dock protocol and discovers DeckBridge the same way.
DeckBridge is for personal and hobby use, and does not replace the Elgato Network Dock. See the Introduction for the full disclaimer.
Multiple decks
Plug in a second deck (a different model — see Limitations) and it becomes its own network dock: own mDNS name, own CORA port pair (see Network ports). The web UI lists every connected deck as a card:
- Pair one at a time. Each deck shows in the Elgato app as a separate Network Dock.
An unpaired card shows an amber "Waiting for Elgato app" chip and the exact
IP : portcopy-chips for the app's Add Network Device… dialog — the port differs per deck (5343, 5345, …), so copy it from that deck's card. - Card flips green ("Paired") when the app connects — no reload. The app remembers paired docks across restarts.
- Click a card to select it — the selected deck gets the live preview and the brightness slider. Each deck keeps its own brightness (also applied per deck from the Elgato app, unless "Ignore brightness from Elgato app" is on).
Unplugging an extra deck removes its card; replugging brings it back automatically.
Permissions
Each permission is requested on first use; no admin / root rights are required.
| Permission | Platform | Why |
|---|---|---|
| Input Monitoring | macOS | Reading HID reports (key presses) from the deck. Grant it to the app or terminal running DeckBridge, then restart it. |
| Local Network | macOS 15+ | Advertising over Bonjour / mDNS and serving the CORA ports on the LAN. macOS may prompt on first run. |
| Firewall allow | macOS / Windows | Inbound TCP on 5343 / 5344 so the Elgato app can connect. Allow it if your firewall prompts. |
| udev rule | Linux | Opening the deck's hidraw device as a non-root user needs a udev rule; without it, DeckBridge fails with Permission denied. |
On Linux, add a udev rule (once), then unplug/replug the device:
sudo tee /etc/udev/rules.d/99-mirabox.rules <<'EOF'
SUBSYSTEM=="hidraw", ATTRS{idVendor}=="6603", MODE="0666"
SUBSYSTEM=="hidraw", ATTRS{idVendor}=="5548", MODE="0666"
SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0300", MODE="0666"
SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0b00", MODE="0666"
SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0c00", MODE="0666"
SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0a00", MODE="0666"
SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0500", MODE="0666"
EOF
sudo udevadm control --reload-rules && sudo udevadm trigger
(6603 = Mirabox 293V3 / HSV293SV3 / K1 Pro, 5548 = Mirabox 293S / Ajazz AKP153,
0300 = Ajazz AKP153E/R (rev. 1 and rev. 2), 0b00 = Mars Gaming MSD-ONE, 0c00 = Mad
Dog GK150K, 0a00 = Risemode Vision 01, 0500 = TMICE Stream Controller.)
Requirements
The /requirements page (tray → Check Requirements) verifies each of these at runtime:
| Requirement | macOS | Linux | Windows |
|---|---|---|---|
| libhidapi | bundled / brew install hidapi | sudo apt install libhidapi-dev | bundled |
| deckbridge-native (Rust lib) | bundled | bundled | bundled |
| mDNS | Bonjour (built in) | avahi-daemon running | built in (Win10 1803+) |
| Tray helper | bundled (installer builds) | — | bundled |
| Free TCP ports | 5343 / 5344 must be free | same | same |
Packaged releases embed libhidapi and the native library, so a source build is the only case that needs a system libhidapi installed.
Files, ports & data
DeckBridge stores no personal data and sends no telemetry.
Reads
- Its own embedded libraries (libhidapi, deckbridge-native) from inside the binary.
- The system libhidapi (source builds, or when overridden via
HIDAPI_LIB). - A handful of environment variables (below). There is no config file.
Writes
-
Native library cache — extracts the embedded libs once per version to:
- macOS:
~/Library/Caches/deckbridge/native-<build-hash>/ - Linux:
$XDG_CACHE_HOME/deckbridge/(or~/.cache/deckbridge/) - fallback: a temp directory if the cache root isn't writable
Old
native-<hash>folders from previous versions are cleaned up automatically. - macOS:
-
Debug image dumps — only when
DECKBRIDGE_DUMP_DIR/DECKBRIDGE_RAW_DUMP_DIRare set. Off by default.
Network ports
| Port | Bind | Purpose |
|---|---|---|
| 5343 | 0.0.0.0 (LAN) | CORA main server — the Elgato app connects here |
| 5344 | 0.0.0.0 (LAN) | CORA child server — image / data channel |
| 5345–5350 | 0.0.0.0 (LAN) | Extra decks — each additional device gets its own CORA pair at +2 per device (max 3 extras) |
| 3000 | 127.0.0.1 only | Web UI |
mDNS _elg._tcp | LAN | Service discovery ("Network Stream Deck") |
Set DECKBRIDGE_BIND=127.0.0.1 to restrict the CORA ports to the local machine. The web
UI is always localhost-only.
Limitations
- Multiple decks: distinct models only — each extra deck must be a different model; a second deck of the same model is ignored. Up to 4 devices total (primary + 3 extras), each its own network dock (own mDNS name and port pair — see Network ports). The web UI shows a live preview for one selected deck at a time (click its card); the others stay static.
- Keys only — no dials, encoders, touchscreens, or LCD strips (Stream Deck +/Plus, Neo, and similar are out of scope).
- Fixed ports — CORA is hard-wired to 5343 / 5344 (extra decks add a fixed +2 offset per device); conflicts with a real Elgato Network Dock or a second DeckBridge instance on the same machine.
- No auth or encryption — the CORA ports trust the LAN; see Network ports.
Environment variables
| Variable | Effect |
|---|---|
DECKBRIDGE_BIND | Bind address for the CORA servers (default 0.0.0.0) |
HIDAPI_LIB | Path to a specific libhidapi |
DECKBRIDGE_NATIVE_LIB | Path to the deckbridge-native cdylib |
DECKBRIDGE_TRAY_BIN | Path to the tray helper binary |
DECKBRIDGE_OPEN | Auto-open the web UI in a browser on start |
DECKBRIDGE_MOCK | Run with a mock device (no hardware) |
DECKBRIDGE_DUMP_DIR | Write each transformed device image here (debug) |
DECKBRIDGE_RAW_DUMP_DIR | Write paired raw + transformed images here (debug) |
Console/web UI log verbosity is fixed at build time (LOG_LEVEL, default info) —
there is no runtime environment variable to change it after the binary is built.