The GUI layer of the COOLJAPAN stack has arrived — and it builds in a fresh container.
Today we’re releasing OxiUI 0.2.0 — the COOLJAPAN-blessed Pure Rust UI layer: a thin, opinionated facade for building desktop and web GUI applications, with no native toolkit anywhere in the build.
No GTK. No Qt. No SDL. No system widgets, no raw AppKit / Win32 / Cocoa bindings. No FFI, no -sys crates. Just Rust — from the constraint solver and the draw-list all the way down to the wgpu surface and the CPU rasteriser. OxiUI exists so that any GUI app in the COOLJAPAN ecosystem can build with a single cargo build in a fresh rust:slim container, with no libgtk-dev, libqt-dev, or libsdl2-dev choreography.
Why OxiUI
For decades, “writing a GUI in Rust” meant binding to something written in C or C++. GTK pulls in a sprawling C runtime. Qt brings a C++ object system and its own build tooling. SDL is C. Even “native” windowing has historically meant raw bindings into Cocoa, Win32, or AppKit. Every one of those is a -sys crate, a system package to install, a C toolchain in your CI image, and a memory-safety boundary you don’t control.
That has real costs. Your Dockerfile grows a paragraph of apt-get install lines. Cross-compiling becomes an afternoon. A cargo build on a clean machine fails until someone tracks down the missing -dev package. And the whole time, the actual UI logic — the part you wrote — is sitting on top of a foundation you can’t audit.
OxiUI removes that foundation and replaces it with Rust. The widgets, the layout, the theming, the text, the rendering — all Rust crates, all memory-safe, all compiled from source. The only thing left at the OS boundary is the GPU driver and the windowing syscalls, which no toolkit can avoid (more on that below).
What we built
OxiUI is not a new widget toolkit competing with the world. It’s a facade: a clean, opinionated front door over two mature Pure Rust UI engines — egui (immediate-mode) and iced (the Elm architecture) — unified under one builder API, one theme system, and one text pipeline. You pick the rendering and interaction style; OxiUI handles the wiring.
The workspace ships as sixteen crates, layered cleanly:
1. The core (oxiui-core) — zero dependencies. Traits, types, reactive state, a constraint solver for layout, the paint / draw-list, and geometry. This is the part that has no opinion about how you render — it’s the shared vocabulary every adapter speaks.
2. Text (oxiui-text) — the bridge to OxiText + OxiFont, OxiUI’s sibling crates for the text problem. Real shaping, rasterisation, IME support, truncation, and word-wrap. No native text stack, no system font API.
3. Theming (oxiui-theme) — dark, light, and high-contrast palettes, DesignTokens, a TypographyScale, and a theme_picker. The COOLJAPAN default theme is one function call. The high-contrast palette targets WCAG-AAA.
4. Rendering — two paths. oxiui-render-wgpu is the GPU surface: a texture atlas, a draw batcher, a clip-stack, and quality presets, all on top of wgpu. oxiui-render-soft is a CPU scanline rasteriser — anti-aliasing, Bézier curves, blend modes, PNG export — for headless and CI environments where there is no GPU at all.
5. Adapters. oxiui-egui wires egui + eframe (palette → Visuals, a StatefulEguiAdapter, font injection) and is the default Pure adapter. oxiui-iced adapts iced 0.14 (IcedUiCtx, palette → iced::Theme, buttons/labels/inputs) as an opt-in alternative. Experimental oxiui-slint and oxiui-dioxus adapters round out the family.
6. Widgets & a11y. oxiui-table is a virtualized table — a RowSource trait with egui and iced backends, sorting and filtering — that materializes only the rows in the current viewport (1 000 rows, ~16 in memory at a time). oxiui-accessibility builds an accesskit a11y tree (A11yNode, A11yTree) that is headless and unit-testable.
7. The web (oxiui-web) — a real wasm32 entry point. Build with wasm-pack, call mount() on a <canvas>, and the same app runs in the browser. Key mapping, mouse/wheel/touch translation, IME composition, clipboard, and drag-and-drop are all there. On native targets it compiles to a stub so --all-features builds stay green.
The whole thing is exercised by 1,964 tests across 16 crates (cargo nextest run --all-features).
Getting Started
Add OxiUI. The default features give you the egui + wgpu GPU path:
[dependencies]
oxiui = "0.2.0"
A complete, runnable app is a single builder chain:
use oxiui::{App, theme};
fn main() -> Result<(), Box<dyn std::error::Error>> {
App::new("My App")
.theme(theme::cooljapan_default())
.content(|ui| {
ui.heading("Hello from OxiUI");
})
.run()?;
Ok(())
}
That’s a real, themed, windowed application — no GTK, no Qt, no SDL anywhere in the dependency tree. The content closure is immediate-mode: you describe the UI each frame, and OxiUI handles the window, the event loop, and the GPU surface.
What’s inside
- Two interaction models, one facade — immediate-mode (egui) by default, Elm-architecture (iced) opt-in, selected via
Backend::{Egui, Iced, Slint, Dioxus}. - GPU or CPU rendering —
wgpu(Vulkan / Metal / DX12 / WebGPU) by default; a Pure Rust CPU scanline rasteriser for headless/CI. - Real text — shaping, raster, IME (including CJK), truncation, and word-wrap via OxiText + OxiFont.
- Windowing via
winit— event loop, IME, and clipboard, with no raw Cocoa / Win32 / AppKit. - Virtualized tables — viewport-based row virtualization through a simple
RowSourcetrait. - Accessibility — an accesskit a11y tree that’s headless and unit-testable.
- Web target — a wasm32
mount()entry point; the same app runs on a<canvas>in the browser. - Theming — dark / light / high-contrast (WCAG-AAA) palettes and design tokens out of the box.
Tips
- Headless and CI? Drop the GPU stack entirely with the software path:
The CPU rasteriser can even export frames to PNG — handy for golden-image UI tests.oxiui = { version = "0.2.0", default-features = false, features = ["software"] } - Prefer the Elm architecture? Turn on the iced backend:
oxiui = { version = "0.2.0", features = ["iced"] } - Building big lists? Use
oxiui-table(thetablefeature). ImplementRowSourcefor your data and only the visible viewport is materialized per frame, regardless of total row count. - Going to the browser? Build
oxiui-webwithwasm-pack build --target web, then in JS:import init, { mount } from './pkg/oxiui_web.js'; await init(); await mount('my-canvas');. - About the OS boundary:
wgpu(Metal/Vulkan/DX12) andwinit(Wayland/X11/Cocoa/Win32) talk to OS-provided drivers at runtime via syscalls — nothing C is linked at build time. That’s why a cleancargo buildjust works. Per the project’s governance, this OS-driver line is the one acceptable boundary; everything at the Rust crate layer stays Pure Rust.
Part of the COOLJAPAN ecosystem
OxiUI is part of NoFFI — the COOLJAPAN initiative to replace every C/C++/Fortran/-sys FFI dependency in the Rust ecosystem with a clean, memory-safe, 100% Pure Rust implementation. OxiUI’s job is the native GUI toolkits: it retires gtk-rs/gtk4 (GTK C), qt-*/qmetaobject (Qt C++), sdl2/sdl2-sys (SDL C), and raw cocoa-rs / windows-rs windowing bindings.
It doesn’t stand alone. OxiUI is built directly on its NoFFI siblings OxiText (text shaping) and OxiFont (font loading + raster), and it’s the GUI layer that other COOLJAPAN apps reach for — data UIs, the OxiMedia previewer, photo viewers, RAG chat UIs, and settings panels — all optionally.
Repository: https://github.com/cool-japan/oxiui
Star the repo if you want a Rust GUI you can build in a clean container, audit end to end, and ship as a single binary. 🦀
Pure Rust UI — sovereign, safe, and FFI-free.
— KitaSan at COOLJAPAN OÜ June 23, 2026