A small Rust UI framework for persistent widgets, custom drawing and optional higher-level composition. Use it for native desktop tools, animated text and interactive canvases. Widgets retain their state; explicit invalidation and frame requests let the event loop sleep when idle.
Version 0.8.0 · Rust 1.88+ · MIT · experimental
| Crate | Responsibility |
|---|---|
fire-ui |
Typed widget ownership, layout, input, scheduling, text and painting contracts. No dependencies. |
fire-ui-widgets |
Controls, design tokens, layout policies, editor, scrolling, menus and virtual lists. |
fire-ui-native |
Desktop windows, input/IME routing and optional platform services. |
fire-ui-fonts |
Shared immutable font bytes and explicit file-face selection; optional mapping. |
fire-ui-text |
Unicode shaping and editing geometry. |
fire-ui-cairo |
Cairo painting with direct or retained X11 presentation. |
fire-ui-gl |
Optional OpenGL painting, retained repainting and rasterized glyph masks. |
The layers are separate dependencies. You can use the core with your own host, write custom widgets, or compose the supplied controls. No Fire Notes checkout, application state or prescribed visual theme is required.
The v0.8.0 GitHub prerelease provides seven crate archives; these crates are not
published to crates.io. Apps select a host, text engine and renderer independently. For a
Linux/X11 app, use path dependencies on fire-ui, fire-ui-widgets,
fire-ui-native, fire-ui-fonts, fire-ui-text and fire-ui-cairo with its x11 feature.
use fire_ui::Element;
use fire_ui_native::{run, WindowOptions};
use fire_ui_widgets::*;
fn main() -> Result<(), String> {
let fonts = fire_ui_fonts::Fonts::load(&["/path/to/app-font.ttf"])?;
run(
Padding::new(Label::new("Hello, Fire UI")).insets(24.0),
WindowOptions::default(),
fire_ui_text::Text::new(fonts.clone())?,
fire_ui_cairo::Cairo::direct(fonts),
)
}The hello example explicitly selects a system font. The minimal example draws a custom widget without loading fonts or optional native services.
cargo run --release -p fire-ui-cairo --features x11 --example hello
cargo run --release -p fire-ui-cairo --features x11 --example minimal
cargo run --release -p fire-ui-studioThe studio is a navigable gallery of everything the framework ships: controls, text editing, a searchable 100,000-row virtual list, a custom animated canvas, a live layout playground and the design tokens themselves, with a light/dark switch. It uses public APIs only — no literal colour, font size or panel coordinate appears anywhere in it.
The native host defaults to X11 windows. Accessibility, agent inspection, clipboard
and dialogs are independent host features. GPU drawing, font coverage and retained
repainting are explicit app choices. OpenGL bitmap-font decoding and rasterized
raster-text are renderer features. See native configuration.
The core and widgets are platform-independent Rust with std. The native host
supports Linux X11/XWayland only. Native X11 interactions are verified using Xvfb.
Browser, mobile, embedded and no_std hosts are not provided.
Supply explicitly selected, licensed font files through fire-ui-fonts::Fonts, or provide owned/static bytes.
Fonts::load owns stable bytes; the optional mmap feature adds unsafe Fonts::map,
which requires the caller to keep the
mapped files immutable for every resource's lifetime. fire_ui_fonts::system_font() is an
optional helper, including a FIRE_UI_FONT override. There is no font discovery
in the native host. The same font resources serve shaping and drawing.
Mixed-direction text shares shaping, selection and visual caret geometry. IME
composition preserves its selection in a temporary display layout.
Agent inspection uses the same semantic actions as accessibility.
It exposes widget identity, values, bounds, supported actions, selection and composition
through the optional inspection feature and Unix socket. The accessibility feature
enables AccessKit, which publishes text runs and selection to native
assistive technology. Linux implements all six AT-SPI EditableText methods with atomic
range edits, undo and asynchronous clipboard reads. Native probes use installed IBus
Cangjie5/XIM and Orca, including its generated speech. Variable-height lists remain
future work.
The performance report records native measurements and their limits. Low idle CPU, memory use, direct pointer response and fast resizing remain requirements. Cairo consumers choose direct drawing without a client framebuffer or a retained client image; OpenGL consumers choose retained repainting separately. Display-server surfaces, glyph resources and GPU costs are measured separately from app memory. The full Fire Notes memory requirement has not yet passed reliably.
Local dev/test profiles keep file/line backtraces and disable incremental caches. Use the Unix storage guard for local builds, including additional worktrees:
python3 tools/build_storage.py cargo build --locked -p fire-ui-studio
python3 tools/build_storage.py cargo test --workspace --locked
python3 tools/build_storage.py check
python3 tools/build_storage.py clean
# A registered sibling worktree can be cleaned explicitly:
python3 tools/build_storage.py --worktree /path/to/fire-ui-worktree clean
python3 -m unittest discover -s tools -p 'test_*.py'The guard checks every registered worktree before and after Cargo: at most 4 GiB
per target and at least 8 GiB free per filesystem. It refuses further builds when
these limits are reached; it never deletes caches automatically. Separate targets
let worktrees compile concurrently; sharing one can make Cargo wait for its build lock.
Cleanup removes native target/debug and target/release contents while preserving
Cargo lock files, and refuses active builds, symlinked targets and tracked files.
It leaves source, artifacts, packaged crates, docs and cross-compilation targets
alone. Those last three can still consume space and require deliberate removal.
Run cleanup after finishing a worktree experiment. Direct Cargo commands and editor
builds bypass the size guard; one build can exceed the preflight budget. Environment
profile overrides can also re-enable incremental output.
Probes own scratch directories with Python TemporaryDirectory and handle INT,
TERM and HUP before removing them. Lean probe targets and consumer workspaces are
deleted on completion; --output retains evidence binaries, inputs, logs and images
for --measure-only. SIGKILL and power loss cannot execute cleanup. New experiments
must use the same lifetime helper, or shell EXIT/signal traps as in
inspection instructions, and keep Cargo targets inside scratch.
The full framework checks are:
cargo fmt --all --check
cargo test --workspace --locked
cargo clippy --workspace --locked --all-targets -- -D warnings
cargo doc --workspace --no-deps --locked
cargo package --workspace --exclude fire-ui-studio --lockedcargo doc --open -p fire-ui --no-deps opens the public API reference locally.
CI builds/tests on Linux and checks the minimum Rust version.
The Linux native probe uses Xvfb, xdotool, Pillow, fonts and a private accessibility bus:
cargo build --release -p fire-ui-studio
python3 tools/native_probe.py --seconds 2 --accessibility --output artifacts/nativeFire Notes is an external consumer. For local co-development, keep its checkout beside Fire UI and use path dependencies.
All crates share workspace.package.version. Keep all internal dependency
versions in sync. This is early ideation: breaking redesigns are expected. Use a
new 0.x minor version for breaking changes and patch versions for compatible fixes.
No compatibility shims are required. Pin a Git tag when you need a fixed snapshot.
Release by running the checks above, committing, tagging vVERSION, and attaching
target/package/*.crate to the GitHub release. Registry publication is separate:
publish crates in dependency order after their internal dependencies are available. Never publish the studio or replace an existing release tag.
See architecture, changelog and project rules. MIT licensed; see LICENSE.