docs/overview

The zenit manual

Build truly native macOS desktop UI in Zig. zenit folds windows, GPU rendering, text, input methods and accessibility into one clear UI model; this manual takes you from your first window to a maintainable production app.

Start in 5 minutes
$zig build run
0.15.2Zig version
MetalCurrent GPU backend
2 tiersPublic API: ui.X and ui.<group>.X
src/main.zig
const std = @import("std");
const ui = @import("ui");
const App = @import("zenit_app").App;

fn mountUi(cx: *ui.Cx, _: *ui.Scope) anyerror!*ui.Node {
    return ui.text(cx, "Hello, zenit!", .{
        .font_size = cx.tokens.font_size.xxxl,
        .color = cx.tokens.color.fg_primary,
    });
}

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();

    const app = try App.init(gpa.allocator(), .{
        .window = .{ .title = "Hello" },
    });
    defer app.deinit();
    try app.runWith(mountUi);
}
Building with Claude Code or another agent? Install the zenit UI dev Skill first.

It packs this manual, the component decision table and real-project pitfalls into instructions your agent loads on demand, so the code it writes follows zenit conventions.

Learning path

Work through it once, in order (about 45 minutes), and you’ll have the whole mental model for building zenit apps on your own.

The architecture you use

Apps depend only on the stable public layer; zenit owns platform and rendering.

LAYERS
zenit.attach(dep, exe) adds exactly two module imports to your executable (ui and zenit_app), then compiles the native bridges and links the system frameworks. Internal modules aren’t in your build graph at all: not “please don’t”, but “can’t”.

More than a set of APIs

These three run through the runtime, the text stack and the tooling. Each is backed by a runnable demo and real-window evidence.

Three principles

Follow them and your code stays clear while zenit is still moving fast.

01
Import only from the public layer

Use ui.*, ui.<group>.* and zenit_app.App. Never reach into internal directories.

02
Let data drive the UI

Persistent state lives in Signals or bound state; derive with Memo, side-effect with Effect.

03
Tokens first

Color, type, spacing and radii come from the theme; when you must go off-scale, say so with ui.arb.

zenit · Dual-licensedFree for open-source projects under GPL-3.0-only; closed-source or commercial products need a commercial license.Contact the author: zongyi.xzy#gmail.com (replace # with @)zenit 4c50245 2026-10-01