UCE is a self-hosted, real-time lighting and show-control platform for studios and small venues. UCE Hub is its main application: a Rust runtime that drives DMX in real time over the network, a REST + WebSocket API, SQLite persistence, and a Vue 3 web interface for patching, scenes, floorplans, and system management.
The Hub is modular. Domain features are maintained in separate repositories (uce-light, uce-resolume) and injected into the Hub at build time, so the core stays small while capabilities are added as modules.
- Networked DMX output over Art-Net and sACN (E1.31), with configurable output nodes, discovery, and per-node routing.
- Real-time runtime driven by a dedicated actor loop (40 Hz / 25 ms tick) designed to stay responsive under bursts of user commands and high-frequency DMX updates.
- Live control over WebSocket — the frontend streams light values (with optional fades) to the backend and receives
dmx_updateframes back; DMX payloads are serialized once at the source and broadcast to all clients. - Fixture library backed by the public Open Fixture Library — browse the catalog, download OFL profiles, and manage a local fixture set. No account or API key required.
- Scenes & gradients — save, apply, import, and export scenes and gradient scenes.
- Floorplan & patching — visual floorplan (dots/beams), soft-patch editing, rooms, and a live patch visualizer.
- Zigbee lighting via Zigbee2MQTT — device discovery, pairing, renaming, capability sync, and color/gradient commands.
- Elgato Key Light control — discovery and command of Elgato devices on the LAN.
- Resolume integration — connect to Resolume, fetch compositions, detect screens, and send commands (runs as a standalone sidecar backend, see below).
- Import / export of DMX config, scenes, floorplans, full projects, and backups.
- System management — service status/control, log access, update check/apply/rollback, DMX interface configuration, local domain settings, and reboot.
- Persistence in SQLite, with optional HTTP Basic auth for the API and token auth for the WebSocket.
UCE Hub is the host application. It owns the runtime, the API router, persistence, networking, and the web shell, and it composes modules directly into its own build:
- Backend (
core/) — the Hub compiles module source into its own crate using Rust#[path]module declarations that point atmodules/uce-light/core/src/...and, where relevant, the Resolume module.UCE Light(DMX/MQTT/library/scenes/floorplan/Elgato) is statically linked into the Hub this way.UCE Resolume's backend instead runs as a separate sidecar binary that the Hub launches and proxies to at runtime. - Frontend (
web/) — before dev/build, a bootstrap step copies each module'sweb/srcintoweb/modules/<module>/src, which Vite exposes through path aliases (@uce-light,@uce-resolume,@hub). Module Vue components are therefore imported and bundled as part of the single-page app.
Because the modules are injected rather than published as packages, you must fetch them into modules/ before building (see Build & Run). A missing UCE Light checkout will fail the build early with a clear message.
uce-hub/
├─ core/ Rust backend (Axum + Tokio runtime, API, persistence, DMX)
├─ web/ Vue 3 frontend (Vite, Pinia, TypeScript)
├─ modules/ Injected module checkouts (uce-light, uce-resolume)
├─ scripts/ Module bootstrap scripts
├─ docs/ Additional documentation
├─ LICENSE
└─ README.md
| Path | Description |
|---|---|
core/src/main.rs |
Bootstrap; declares injected UCE Light modules via #[path] |
core/src/routes.rs |
REST + WebSocket router composition |
core/src/state.rs |
Runtime actor, command channel, frame fetch, broadcast |
core/src/network.rs |
Art-Net / sACN output |
core/src/module_runtime.rs |
Resolume sidecar lifecycle and proxy target |
core/src/handlers/ |
HTTP/WebSocket handlers (Hub + injected module handlers) |
web/src/ |
Vue app shell, stores, floorplan, patch UI |
web/scripts/ensure-light-module.mjs |
Copies module web/src into the build |
- Backend: Rust (edition 2024), Tokio async runtime, Axum 0.7 (HTTP + WebSocket),
tower-http, SQLx + SQLite,redb,artnet_protocol,sacn,rumqttc(MQTT/Zigbee2MQTT),reqwest,parking_lot,clap. - Frontend: Vue 3 (
<script setup>Composition API), Pinia, TypeScript, Vite, ESLint.
- Rust toolchain (stable) with Cargo
- Node.js (18+; CI uses 20/22) and npm
The Hub needs the UCE Light and UCE Resolume sources under modules/ before it can build. Run from the repo root:
# Linux / macOS
./scripts/bootstrap-light-module.sh
./scripts/bootstrap-resolume-module.sh
# Windows PowerShell
./scripts/bootstrap-light-module.ps1
./scripts/bootstrap-resolume-module.ps1These scripts sync from a local sibling checkout if present, otherwise clone from the module repositories.
cd core
cargo run # dev run
cargo build --release # release binary (target/release/uce-hub-core)By default the backend serves the API and WebSocket on http://localhost:3000.
cd web
npm install
npm run dev # Vite dev server on http://localhost:5173
npm run build # type-check + production build into web/distThe dev, build, and lint npm scripts automatically run the module-injection step, so make sure step 1 has been completed first.
# Backend
cd core && cargo fmt -- --check && cargo clippy -- -D warnings && cargo test
# Frontend
cd web && npm run lint && npm run buildConfiguration is persisted in SQLite (not a runtime JSON file):
- Default DB: OS app-data directory (
com/uce/uce-hub/uce-hub.db), fallbackdata/uce-hub.db UCE_DB_PATH— override the database path
Useful environment variables:
UCE_FRONTEND_PATH— static frontend directory served by the backendUCE_API_AUTH— API credentials asusername:password(HTTP Basic auth)UCE_RUNTIME_PERSIST_MS/UCE_RUNTIME_DEBOUNCE_MS— runtime snapshot persistence tuningUCE_DEV_MODE— enable DEV mode (1/true/on) for simulated features
WebSocket auth accepts a token via Sec-WebSocket-Protocol (uce-hub-auth.<token>), with a ?token=... query fallback.
Fixture profiles come from the Open Fixture Library, a public, open-data project. The Hub enumerates the OFL catalog and downloads profiles as raw OFL JSON directly from GitHub — no license key or account is needed. Downloaded profiles are cached in your local fixture library and can be managed from the UI.
Releases are published to GitHub Releases. Tagging hub-v* builds an OTA package (release binary + web/dist) with a SHA-256 checksum and publishes it as a GitHub release. Modules ship on their own tags (light-v*, resolume-v*): the Resolume sidecar updates independently, while the statically linked UCE Light backend ships with the Hub. Frontend-only module changes can be released via their module tags.
Contributions are welcome. Please open an issue to discuss substantial changes first, keep the CI checks green (cargo fmt/clippy/test and npm run lint/build), and note that all contributions are accepted under the project's license. See docs/ for additional developer notes.
This project is distributed under the GNU General Public License, version 3 or later (GPL-3.0-or-later). See the LICENSE file for the full text.
Copyright (C) 2026 Maxime Deprince