Skip to content
qxukenPublic

About

Data-driven UI library for Rust, with clay-style layout, a wgpu renderer, and Lua, C and JSX frontends.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

kui

kui is a UI library for Rust. You describe what is on screen as a tree of boxes and text; kui lays it out, draws it, and hands back what the user did as plain data. Underneath is a clay-style flat-array layout solver, on top an iced-style view / on_event loop, and text shaping is part of the core. Because a frame is data all the way down, Lua, C and Node bind to the same contract the Rust builders use.

Kit also supports native presentations as code in Lua/Teal and TSX: interactive content, reveals, private presenter views and PNG export. Theme presets accept the project's fonts, colors and sizes. Try kui run addons/kit/samples/presentations -- --presenter.

Crates

crate role
kui-native The crate most apps use: a window (winit), the GPU renderer, the stock widgets and the App trait crates.io · docs.rs
kui-core The bindable contract: the flat per-frame tree, the flex solver, the text stack (cosmic-text + a glyph atlas), events as data, resources, the quad display list crates.io · docs.rs
kui-wgpu The wgpu backend: one instanced pipeline (rounded rects, borders, glyphs), one draw call per frame crates.io · docs.rs
kui-value Plain data on no kui core: Value, its JSON reader, the message conversions, Lua conversions behind lua; re-exported by kui-core crates.io · docs.rs
kui-channel The data channel: named, typed columns one handle names, read from any thread, filtered, sorted and laid on lanes in Rust; re-exported by kui-core crates.io · docs.rs
kui-trace The recording format: its reader and writer, the kui-trace tool (dump, stats, convert, diff, synth) and, behind lua, a recording as channels crates.io · docs.rs
kui-derive #[derive(Message)]: an enum that travels through the frame as data and comes back typed crates.io · docs.rs
kui-lua Lua extensions via mlua: scripts return table trees and receive events as tables crates.io · docs.rs
kui-ffi The C API (a cdylib, a staticlib on request, plus include/kui.h): flat builder calls, opaque KuiValue payloads, repr(C) draw data, a windowed runner via callbacks, and CExtension, a C shared library as a guest in another host's frame crates.io · docs.rs
kui-node The Node.js addon (napi-rs) behind the @qxuken/kui npm package: JSX views lowered into the IR in one call per frame, Elm-style messages as data. Ships through npm, not crates.io packages/kui

Install

cargo add kui-native

which writes the one line a project needs:

[dependencies]
kui-native = "0.1.0-alpha.79"

Every release so far is an alpha. A requirement like "0.1.0-alpha.34" is a floor that admits every later alpha; Cargo.lock keeps the version you tested, and "=0.1.0-alpha.34" pins it in the manifest.

macOS and Windows need nothing beyond a Rust toolchain. On Linux the build wants pkg-config and ALSA's headers (libasound2-dev on Debian and Ubuntu). A window loads the rest at run time: libxkbcommon (plus libxkbcommon-x11 on X11), the X11 client libraries (libX11, libXcursor, libXrandr, libXi) or libwayland-client, and libvulkan with a driver or libEGL. A missing one fails when the window opens, with the library's name in the error. File dialogs go through the XDG desktop portal; without one on the session bus, every dialog answers as if cancelled.

The first build takes a few minutes: it compiles a GPU renderer.

From C or Odin there is nothing to build: each release on GitHub carries, for each of linux-x64, linux-arm64, darwin-arm64 and win32-x64, kui-ffi-<version>-<platform>.tar.gz, that platform's libkui_ffi with the windowed runner, shared and static, and kui-ffi-core-<version>-<platform>.tar.gz, the library without it for a host that brings its own window, shared only (.zip for win32-x64). Each carries kui.h, the Odin package and a README.md with the link lines.

Hello, window

The whole of kui in one program. An app is a type with a view that declares the frame from scratch, and a launcher opens a window around it.

use kui_native::{App, TextStyle, Ui};

/// The app is any type. It holds the state; this one has none yet.
struct Hello;

impl App for Hello {
    /// Called once per frame. Everything on screen is declared here,
    /// from scratch, every time.
    fn view(&mut self, ui: &mut Ui<'_>) {
        let theme = ui.theme();
        ui.text("Hello, kui", TextStyle::new(24.0).color(theme.fg));
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    kui_native::app("Hello").size(360.0, 200.0).run(Hello)
}

Put that in src/main.rs and cargo run. From a checkout of this repository it is cargo run -p kui-native --example tutorial_01_hello.

That program is step one of the kui book: ten short chapters, each the last plus one concept (layout, messages, controls, lists, keys, floats, motion, effects, a test), and each a program under examples/rust/tutorial. Read it first.

Developing

The checkout pins Node in .node-version, Rust in rust-toolchain.toml and the fuzz nightly in fuzz/rust-toolchain.toml. mise reads those files; the remaining build and release tools are in mise.toml, with downloads and checksums for the four supported platforms in mise.lock.

mise install --locked
mise run bindings-setup
mise run test
mise run release-prep

Use mise exec -- <command> without shell activation. The C compiler, platform SDK and system libraries still come from the machine; see releasing for the native verification prerequisites. To change a tool, update its version file and run mise lock --platform linux-x64,linux-arm64,macos-arm64,windows-x64. CI uses the same files in locked mode.

Documentation

  • The kui book: the path in, one concept a chapter, every code block pulled from a runnable program. Its source is docs/book.
  • API reference on docs.rs: kui-native, kui-core, kui-wgpu, kui-derive, kui-lua, kui-ffi.
  • docs/howto.md: "How do I…", about twenty questions a developer arrives with, two sentences each and a pointer.
  • docs/props.md: every prop, element, event, warning, theme role and metric, with its JSX, Lua, C and Odin spelling in the same row. Generated from the schema, so it cannot drift.
  • examples/README.md: the map of every example in Rust, C, Lua, Node and Odin, what each shows and how to run it.
  • docs/guide.md: testing without a window, the devtools panel, the same app from Node, Lua and C, and the reference documents in detail.
  • docs/design.md: the design notes (one schema for every binding, events, focus, modals, transitions, text, windows, audio, the C ABI) and the layout solver pass by pass.
  • docs/performance.md: the benchmark table and what it says, editing latency, frame pacing.
  • docs/releasing.md: the registries, how a release is cut, CI, the smoke rounds and the audits.
  • docs/status.md: what v0 does not do, by area.
  • docs/adr: design records, the decisions that are hard to reverse and would look arbitrary without their context.
  • CHANGELOG.md: per release, what was added and, separately, what an app can delete.
  • packages/kui: the Node package, @qxuken/kui: JSX views, an Elm-style update, a headless createApp and the same devtools.

License

MIT, see LICENSE.

About

Data-driven UI library for Rust, with clay-style layout, a wgpu renderer, and Lua, C and JSX frontends.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages