Expand description
mirui — a no_std, ECS-driven UI framework for embedded, desktop,
and (planned) WebAssembly. Renders with 24.8 fixed-point subpixel
precision on a software rasterizer designed for MCUs without an FPU;
optionally runs on top of SDL2 (CPU or hardware-accelerated) on
desktop.
§Quick Start
[dependencies]
mirui = { version = "0.24", features = ["sdl"] }The snippet below builds against mirui’s default features and is
verified by cargo test --doc. Swap FramebufSurface for
mirui::surface::sdl::SdlSurface::new("hello", 480, 320) (with the
sdl feature) to run on a desktop window instead of into a
user-supplied flush callback.
use mirui::prelude::*;
use mirui::surface::framebuf::FramebufSurface;
use mirui::draw::texture::ColorFormat;
use mirui::types::Rect;
let backend = FramebufSurface::with_format(
480, 320, ColorFormat::RGBA8888,
|_bytes: &[u8], _area: &Rect| { /* push to your display */ },
);
let mut app = App::new(backend);
app.with_default_widgets().with_default_systems();
let root = WidgetBuilder::new(&mut app.world)
.bg_color(ColorToken::Surface)
.id();
ui! {
:(
parent: root
world: &mut app.world
:)
header (
bg_color: ColorToken::Primary,
text_color: ColorToken::OnPrimary,
text: "Hello mirui!",
border_radius: 8
) {}
};
app.set_root(root);
app.run();§Other targets
mirui also runs bare-metal on RISC-V and ARM Cortex-M MCUs through
surface::framebuf::FramebufSurface, and a Cargo workspace
template builds the same UI code on both desktop and embedded
targets unchanged. The full walkthrough — including ESP32-C3
wiring, the workspace layout, and a recipe for adding new target
crates — lives in docs/quickstart.md.
§Module map
app: theAppentry point andPlugintrait.ecs: World, Entity, Component, Resource, Query, System, SystemScheduler.widget: widget tree primitives (Style, ComputedRect, View, Theme, Dirty).components: built-in widgets — buttons, sliders, lazy lists, effects.draw: software rasterizer, paths, textures, draw commands.surface: backend trait + bundled SDL2 / framebuffer / SDL_GPU implementations.event: input dispatch, gestures, hit-testing, focus.anim: easing, springs, motion components.layout: flexbox + absolute positioning + dimension types.plugins: bundledAppplugins (clock, perf, FPS, input feedback).
Modules§
- anim
- app
- cache
- components
- draw
- ecs
- event
- feedback
- Cursor + rotary input feedback overlays.
- layout
- perf
- Span-based perf tracing. Use
crate::trace_span!/#[crate::trace_fn]; this module is the storage layer. - plugin
- plugins
- prelude
use mirui::prelude::*;brings in the types and macros that nearly every application file needs:App, the layout module,Color/Dimension/Fixed,Entity/World, the widget builder, theme tokens, and theui!macro. Surface backends, individual widget kinds, and plugins stay on their canonical paths so the prelude doesn’t pin a platform choice.- surface
- timer
- Declarative timers —
Timercomponent fires a callback at scheduledMonoClockinstants. Reset drift mode (no catch-up). Lifecycle variants cover one-shot, periodic, bounded counts, and bounded wall deadlines. See.local/specs/timer/design.mdfor the full surface. - types
- widget
- Widget kinds and their shared infrastructure.
Macros§
- trace_
span trace_span!("name")— RAII statement: guard lives until end of scope. Multiple calls in one scope each get a unique binding.- ui