Overview
A retained-mode GUI framework in Rust for macOS, Windows and Linux.
zgx is a retained-mode GUI framework in Rust for macOS, Windows and Linux. Components mount once and fine-grained signals update only the nodes that depend on them, so an idle window does no work and a busy one repaints only what changed. Interfaces are written in Rust or in Luau scripts that hot reload without losing state. It is young (0.1, used from git) and its API still changes.
What it has
- Layout as CSS’s flexbox and grid do it, defaults included: children stretch across and shrink to fit (
min-width: auto), grids, wrapping, percentages, absolute positioning,display: contents, right-to-left with logicalstart/endedges, and layouts that answer the room they have. - Text: shaped rich text with font fallbacks, selectable documents (drag, double and triple press, copy as HTML), editors with undo, clipboard, spellchecking, IME (Japanese, Chinese, Korean) and bidirectional text.
- Paint: a wgpu renderer (Metal, Direct3D 12, Vulkan; GL on Linux where no Vulkan driver is) that redraws only damaged regions, with rounded borders, gradients, shadows, backdrop blur, SVG, images, canvas drawing and custom WGSL fills.
- Controls: buttons, inputs, checkboxes, sliders, progress, virtual lists, scroll views with native scrollbars and rubber-banding, menus, popovers, modals, tooltips, web views (WebKit on macOS, WebView2 on Windows) and terminals (Ghostty, on macOS).
- Components (
zgx-components): a data grid, a tree view, a calendar, a date picker and a time field, a combobox, a select, tabs, toasts, a command palette, a segmented control, a stepper, a disclosure and an accordion, built on the controls above, keyboard complete and accessible. - The platform: native menus and dialogs, multiple windows, the clipboard and primary selection, drag and drop, touch and pen, the system’s accent, appearance, text size, reduced motion, contrast and transparency, and the user’s language direction.
- Accessibility through AccessKit (VoiceOver, Narrator, Orca): roles, headings, live regions, selection and keyboard-only use, with focus groups as ARIA’s composite widgets.
- Scripting: Luau with types, a linter, hot reload that keeps state, anime.js-style animation, sandboxed plugins, and
zgx-runto run a script as an app. Release builds carry scripts compiled into the binary.
Quick start
In Rust, with the dependencies getting started lists (zgx’s crates from git, and the forks it builds with):
use zgx::compose::prelude::*;
use zgx_desktop::{Application, WindowOptions};
fn main() -> Result<(), Box<dyn std::error::Error>> {
Application::new()
.window(WindowOptions { title: "Hello".into(), ..Default::default() })
.run(|cx| {
let count = cx.ui.signal(0);
let shown = count.clone();
cx.render(
row()
.p(24.)
.gap(12.)
.child(button().child(text("Add")).on_click(move || {
count.set(count.get() + 1);
}))
.child(text_signal(move || format!("Clicked {} times", shown.get()))),
);
})
}
In Luau: put this in hello/app.luau and run zgx-run hello/ (LUAU_CXXFLAGS=-DNDEBUG cargo install --git https://github.com/zeronsh/zgx zgx-run). Saving the file updates the window and keeps the count.
local count = ui.state("count", 0)
return ui.row {
p = 24,
gap = 12,
ui.button { on_click = ui.add(count, 1), "Add" },
ui.text { "Clicked {count} times" },
}
The examples run from a checkout:
cargo run --release -p zgx-desktop --example gallery
cargo run --release -p zgx-run -- crates/zgx-script/examples/mail
cargo run --release -p zgx-run -- crates/zgx-script/examples/code_editor path/to/file.rs
cargo run -p zgx-script --bin zgx -- check crates/zgx-script/examples/mail
zgx check type checks scripts with luau-lsp, which it needs on the PATH; zgx lint needs nothing. On Linux, install the fontconfig, xkbcommon and D-Bus development packages and pkg-config. On Windows, use the MSVC toolchain (notes).