DeUX [dø]¶
DeUX is a Python SDK for building standalone applications for Elgato Stream Deck devices. Instead of tethering the Stream Deck to a Windows or macOS PC, DeUX allows it to run from any Python-capable device, including Raspberry Pi systems for home automation, dashboards, kiosks, and embedded control panels.

Features¶
- Multi-deck multi-screen support via
DeckManager - Auto-discovery, hot-plug detection, and auto-reconnect via
DeckManager - Screen-based navigation with atomic screen switching
- Key slots with event decorators (press, release, press_release, hold)
- Encoder slots for rotary dial events (turn, press, release, press_release, hold)
- TouchStrip and InfoScreen support
.duipackage format: declarative touchscreen card UIs using SVG layouts + YAML manifests with data bindings- Iconify icon integration
- Supports Stream Deck (Classic 15-key), Stream Deck XL, Stream Deck Neo, Stream Deck+, and Stream Deck+ XL
System requirements¶
- Python 3.11+
- HIDAPI (For USB HID communication)
Quick Start (macOS)¶
Install system dependencies, clone the repo, and run the example:
brew install hidapi
git clone https://github.com/graphras-com/DeUX.git
cd DeUX
python3 -m venv .venv
source .venv/bin/activate
pip install .
python examples/streamdeck.py
Quick Start (Linux)¶
Install system dependencies, clone the repo, and run the example:
apt-get install libhidapi-dev
git clone https://github.com/graphras-com/DeUX.git
cd DeUX
python3 -m venv .venv
source .venv/bin/activate
pip install .
python examples/streamdeck.py
Installation¶
Install directly from GitHub:
Or clone and install locally:
For development:
Usage¶
import asyncio
from deux import DeckManager, DuiKey
async def main():
manager = DeckManager()
@manager.on_connect()
async def handle(deck):
screen = deck.screen("main")
# DuiKey accepts a built-in package name (e.g. "IconKey") or a PackageSpec
# returned by load_package(). See docs/guides/dui-repository.md for details.
key = DuiKey("IconKey")
key.set("label", "Hello")
key.set("icon", "mdi:hand-wave")
@key.on("click")
async def on_click():
print("Clicked!")
screen.set_key(0, key)
await deck.set_screen("main")
async with manager:
await manager.wait_closed()
asyncio.run(main())
Note:
on_connect()is a decorator factory (call with parens) and accepts optionalserial=/deck_type=filters.on_disconnectis a property — use it bare, without parens (@manager.on_disconnect).
Configuration¶
No environment variables are required. Device capabilities are auto-detected from hardware.
.dui packages are configured via YAML manifests defining bindings (text, image, visibility, color, range, slider, toggle, iconify) and event mappings.
DeUX ships with three ready-to-use packages — IconKey, PictureKey, and DashboardCard — that the quick-start example uses by name. See the DUI Repository & Built-in Packages guide for the full catalogue and instructions on registering your own package directories. To author new packages, see Creating DUI Packages.
Development¶
Run tests:
Run tests with coverage (95% threshold):
Lint:
Type check:
Security¶
- Secrets scanning via Gitleaks runs on every CI pipeline with full git history scanning
- No secrets or credentials are stored in the repository
CI/CD¶
GitHub Actions orchestrates all checks via ci.yml:
- Lint -- Ruff
- Build -- Package build verification
- Type check -- mypy (strict mode)
- Tests -- pytest across Python 3.11, 3.12, 3.13 with 95% coverage threshold
- Secrets scan -- Gitleaks
- Release -- Triggered on
v*tags after quality gate passes
Dependabot is enabled for weekly updates of pip and GitHub Actions dependencies.
Contributing¶
Contributions are welcome. Please open an issue or pull request. This project follows the Contributor Covenant v2.0 code of conduct.
License¶
Apache-2.0 -- see LICENSE.