Skip to content

kozan-rs/kozan

Repository files navigation

Kozan

A native UI engine for Rust built on browser architecture.

Apache-2.0 Rust 1.85+

Roadmap | Vision


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

Apache-2.0.

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.

About

The Rust UI Platform — a browser-level engine that frameworks are built on

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors