Hi! I've been working on zaxis, an immediate-mode GUI library for desktop tools built on winit and wgpu. 0.0.5 is on crates.io. It's an early development release and the API will still change, so I'd like feedback while that's cheap.
- crates.io: crates.io: Rust Package Registry
- Docs: zaxis · zaxis
- Source (MIT): GitHub - nihmadev/zaxis · GitHub
What it is
zaxis::run(app) owns the event loop, repaint scheduling and GPU recovery. You implement App::update and build the UI inside it:
use zaxis::{App, Context, Frame, Window}; #[derive(Default)] struct Counter(u64); impl App for Counter { fn update(&mut self, context: &mut Context, _frame: &mut Frame<'_>) { Window::new("Counter").show(context, |ui| { if ui.button("Increment").clicked() { self.0 += 1; } ui.label(format!("Count: {}", self.0)); }); } } fn main() -> Result<(), zaxis::RunError> { zaxis::run(Counter::default()) } It's event-driven: it repaints only when something needs it, and animations schedule their own next repaint.
Why not egui?
It's the same niche, and egui is far more mature. zaxis is a smaller, independent library with a different packaging of everyday tasks:
- built-in motion: hover/reveal transitions, plus tweens, springs and keyframes with automatic repaint deadlines
- images and SVG load asynchronously with no loader registration
- a larger set of widgets out of the box, including
Dock,TreeView,Table, virtualizedListBox, nested popups,PanZoom, an actions/keymap registry - AccessKit integration, with screen-reader checks done on Windows only so far
- user WGSL fragment shaders for rectangles ("materials"), and optional iOS-style glass/backdrop blur
The part I'd most like feedback on: embedding
EmbeddedRenderer works over a wgpu::Device/Queue you already own. You can prepare + record into your own render pass, or render_to a texture, with no window involved. Input goes through Context::on_input(InputEvent). See examples/embed.rs (zaxis inside a host's own wgpu scene) and the docs page "Embedding in a wgpu host".
There's also an experimental crate, z-hook, that draws a zaxis UI over another process's frames (a debug overlay, a mod menu, a tool inside a 3D editor) via a Vulkan implicit layer. It's meant for processes you control or that allow it, and it does not inject itself into anything.
Honest status
z-hook: run and checked only for Vulkan on Linux (Mesa) with X11 input. The Windows DXGI/D3D11/D3D12 paths compile but have never been run. No OpenGL, no macOS, no Wayland hosts.- Embedding: pixel-tested on Vulkan (Mesa, Intel) only. Metal, DX12 and a real engine's frame graph were not tried.
- Browser: the same
zaxis::runbuilds forwasm32-unknown-unknown(WebGPU, WebGL2 fallback), but only Chrome has been checked. - Accessibility: UI Automation tested with Narrator on Windows 11. NVDA, JAWS, VoiceOver and Orca have not been tried.
- Text: complex shaping and bidi work, but no italic, no variable-font axes, and the multi-line
TextEdithas no search or completion.
The full list is in the docs under "Limitations".
What I'd like to hear
- Is the
App::update+zaxis::runshape reasonable, or would you want something different? - If you embed immediate-mode UIs in your own wgpu renderer, what is missing from
EmbeddedRenderer? - If you have a Windows/macOS GPU setup, running
cargo run --example demoandcargo run --release --example embedand telling me what breaks would help a lot.
Issues and PRs are welcome on GitHub. Thanks for reading!
(Disclosure: parts of the code and documentation were written with AI assistance and reviewed by me.)
1 post - 1 participant
