egui_mobius is a framework for building flexible, robust, and
professional grade applications. It supports both native desktop
and WASM.
The hallmarks of a professional application are robust threading support and async handling, and sleek and modern UI with dockable panels that allow a user to have the most customizable and ergonomic layout.
egui_mobius addresses these aspects; it assembles dockable panels as citizens and coordinates their interaction with a substrate built upon egui_mobius_reactive. This leads to a cohesive and systematic way to assemble an application, which is the reason it's a framework.
A citizen is a panel. A docked, movable, resizable region of the application window with a stable identity and a known set of widgets inside it.
Once a panel implements the Citizen trait it becomes a self-contained
unit you drop into any host app: cargo add the crate, declare one
Dynamic<T> field on shared state, add a TabKind variant, render
it in your TabViewer. No event-bus wiring, no glue. Real apps grow
by accumulating citizens, not by extending a core. The Dispatcher
is the registry those citizens register with — the familiar
backend-registry pattern, applied to UI panels.
The shipped citizens — egui_lens (reactive event
logger) and egui_quill (syntax-highlighted
editor) — are the canonical examples. Same pattern applies to any
third-party citizen published on crates.io. This is what lets you
assemble professional-grade applications from parts rather than
hand-building each one from scratch.
Compile-time plug-ins: adding a citizen rebuilds the host app — Rust has no stable plug-in ABI, so this is not a runtime extension load. The four-line integration is small enough that it feels plug-in-shaped in practice.
The book covers the design and walks through the examples end-to-end.
Most apps fit one of three architectural levels. Pick the one that matches your app's complexity — the ecosystem supports each:
| Level | What you reach for | When | Examples |
|---|---|---|---|
| 1 | Shared Dynamic<T> + Dispatcher for panel activation |
Pure UI; no backend | getting_started, citizen_dock |
| 2 | Above + AppMessage routed through Dispatcher::handle |
Synchronous backend (filter, parser, anything in-process) | filter_plotter 🌐, citizen_fetch |
| 3 | Above + egui_mobius signal/slot + AsyncDispatcher |
Async / multi-threaded backend | citizen_signal_async |
🌐 = WASM-enabled (runs in browser)
filter_plotter is the tutorial example — the book walks through
it file by file. It also serves as the reference implementation for
WASM deployment.
# Level 1 — pure UI / panel coupling
cargo run -p getting_started # smallest possible citizen app
cargo run -p citizen_dock # citizen + egui_dock, three panels
# Level 2 — shared state + backend routing
cargo run -p filter_plotter # tutorial: biquad filter + plotter (WASM-ready!)
cargo run -p citizen_fetch # backend thread doing HTTP fetches
# Level 3 — signals/slots + async
cargo run -p citizen_signal_async # citizen + signal/slot + Tokio backendfilter_plotter can run as a web application:
# Install trunk (one-time)
cargo install trunk
rustup target add wasm32-unknown-unknown
# Build and serve
cd examples/filter_plotter
trunk serve --openSee examples/filter_plotter/README.md
for details.
Other examples (reactive primitives in isolation, signal/slot
without citizens, etc.) are catalogued in
examples/README.md.
| Crate | Role |
|---|---|
egui_citizen |
The citizen pattern — panel identity, reactive lifecycle state, dispatcher for activation arbitration and message routing. Where most app code sits. |
egui_mobius_reactive |
Thread-safe reactive primitives: Dynamic<T> for shared cells, Derived<T> for auto-recomputed values. The cross-panel coupling layer. |
egui_mobius |
Signal/slot bus + AsyncDispatcher for cross-thread async backends. Needed at level 3. |
egui_mobius_widgets |
Stateful widget toolkit for retained-mode-style composition. |
egui_lens |
Reactive event logger component — terminal-style log panel with custom log types, per-type colors, filtering, and file export. The canonical logger across the framework; see examples/logger_component. |
egui_mobius_components |
Predecessor logger built on the older signal/slot architecture. Superseded by egui_lens. Kept for backward compatibility; new code should use egui_lens. |
- egui_mobius_template — project skeleton for new applications.
- CopperForge — real-world reference implementation: a PCB gerber inspection tool built end-to-end on the citizen pattern.
- Contributions welcome — fork, branch, PR.
- Licensed under MIT.
- Questions or discussion: open an issue or use GitHub Discussions.
