1 unstable release
Uses new Rust 2024
| 0.1.0 | Mar 24, 2026 |
|---|
#264 in Operating systems
1MB
22K
SLoC
Kozan is a platform layer — DOM, events, style, layout, paint, scroll, compositing — that UI frameworks build on top of. Two frameworks on Kozan share the same tree, the same event system, and the same rendering pipeline.
This is experimental software. APIs change without notice.
use kozan::prelude::*;
fn main() -> kozan::Result<()> {
App::new().window(WindowConfig::default(), build_ui).run()
}
fn build_ui(ctx: &ViewContext) {
let doc = ctx.document();
let row = doc.div();
row.style().flex().gap(px(16.0)).pad(px(20.0)).bg(rgb8(44, 62, 80));
row.append(doc.create_text("Hello, Kozan!"));
doc.body().child(row);
}
Pipeline
DOM → Style → Layout → Paint → Composite → GPU
Three threads per window. Main thread routes OS events. View thread runs the DOM, style, layout, and paint. Render thread runs the compositor and GPU — scroll happens here at vsync rate, independent of layout.
Crates
| Crate | |
|---|---|
kozan |
Facade — re-exports everything |
kozan-core |
DOM, events, style, layout, paint, scroll, compositor |
kozan-primitives |
Geometry, color, arena allocator |
kozan-scheduler |
Event loop, task queues, async executor |
kozan-macros |
Derive macros for Element, Node, Props |
kozan-platform |
Window management, threading, renderer traits |
kozan-winit |
winit adapter |
kozan-vello |
Vello + wgpu backend |
Usage
Styling
Two ways — inline CSS strings or the type-safe builder:
// CSS string (parsed by Stylo)
div.set_attribute("style", "display: flex; gap: 16px; padding: 20px");
// Builder API
div.style().flex().gap(px(16.0)).pad(px(20.0)).bg(rgb8(44, 62, 80));
CSS classes
Load a stylesheet and toggle classes:
doc.add_stylesheet(include_str!("../assets/dashboard.css"));
card.class_add("card");
card.class_add("card-blue");
card.class_remove("card-blue");
Events
btn.on::<ClickEvent>(|event, ctx| {
println!("clicked at ({}, {})", event.x, event.y);
});
// Capture phase
container.on_capture::<ClickEvent>(|event, ctx| {
ctx.stop_propagation();
});
// One-shot listener (auto-removed after first call)
btn.on_once::<ClickEvent>(|_, _| {
println!("only fires once");
});
Async tasks
ctx.spawn(async move {
sleep(Duration::from_millis(500)).await;
card.class_add("visible");
progress_bar.style().w(pct(75.0));
});
DOM manipulation
let doc = ctx.document();
let container = doc.div();
let child = doc.div();
let text = doc.create_text("Hello");
container.append(child);
child.append(text);
doc.body().child(container);
// Query
let first = container.first_child();
let kids = container.children();
// Remove
child.remove();
What works today
Layout: block, flexbox, grid (tracks, repeat, minmax, named areas, auto-placement), inline text with shaping (HarfBuzz), RTL/bidi, float (partial).
CSS: width/height/margin/padding (px, %, auto), border (width, color, radius), background-color, color, opacity, font-size/weight/family/style, text-align, text-decoration, visibility, overflow (visible, hidden, scroll), gap, aspect-ratio, box-shadow, outline.
Events: click, dblclick, mousedown/up/move/enter/leave/over/out, contextmenu, keydown/keyup, wheel, focus/blur/focusin/focusout, scroll, resize. Full W3C capture/target/bubble dispatch.
Rendering: rectangles, rounded rectangles, borders (solid), text (pre-shaped glyphs), lines, box shadows, outlines, opacity layers, clip regions, scroll transforms.
Elements: div, span, p, h1-h6, a, button, input (18 types), textarea, select, img, canvas, video, audio, table, ul/ol/li, form, section/article/nav/aside, and more.
Not yet supported
- Animations and transitions
- Gradients (linear, radial, conic)
- Images (element exists, rendering stubbed)
- Filters (blur, brightness, etc.)
position: fixed/position: sticky- Text selection, clipboard
- Media playback (video/audio stubs only)
- Custom properties (CSS variables)
Build
cargo run --example hello-world
cargo run --example dashboard
cargo test --workspace
Requires Rust 1.85+.
License
The name "Kozan" is a trademark of Youssef Khalil. The code is yours to use under Apache-2.0. The name and logo are not — forks can't use them to imply official status. Same policy as Rust and Firefox.
lib.rs:
kozan — the Kozan UI platform.
Single entry point for application authors. Re-exports everything needed to build a Kozan application — no internal crate knowledge required.
Quick start
use kozan::prelude::*;
fn main() -> kozan::Result<()> {
App::new()
.window(WindowConfig::default(), |ctx| {
let doc = ctx.document();
let div = doc.div();
div.style().w(px(200.0)).bg(hex("#ff4444"));
doc.body().child(div);
})
.run()
}
Feature flags
| Flag | What it enables | Default |
|---|---|---|
winit |
winit windowing backend | yes |
vello |
vello/wgpu GPU renderer | yes |
Dependencies
~35–57MB
~1M SLoC