DeckUI¶
A high-level, asyncio-native Python library for Elgato Stream Deck devices. Define screen layouts, key actions, encoder controls, and touchscreen card UIs using a declarative, event-driven API.

Features¶
- Multi-screen Multi-deck 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+, Mini, Neo, and XL
System requirements¶
Quick Start (macOS)¶
Install system dependencies, clone the repo, and run the example:
brew install hidapi vips
git clone https://github.com/graphras-com/DeckUI.git
cd DeckUI
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 libvips-dev
git clone https://github.com/graphras-com/DeckUI.git
cd DeckUI
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¶
Basic key handling¶
import asyncio
from deckui import DeckManager
async def main():
manager = DeckManager()
@manager.on_connect()
async def handle(deck):
screen = deck.screen("main")
@screen.key(0).on_press
async def on_home():
print("Home pressed!")
await deck.set_screen("main")
async with manager:
await manager.wait_closed()
asyncio.run(main())
Using .dui packages¶
from deckui.dui import load_package, DuiCard
spec = load_package("./AudioCard.dui")
card = DuiCard(spec)
card.set("artist", "The Beatles")
@card.on("toggle_play_pause")
async def handle():
...
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.
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.