ZigTUI
A fast, allocation-free TUI library for Zig
zig fetch --save git+https://github.com/adxdits/zigtui.gitCell-Based Diffing
Only redraws cells that actually changed your terminal stays flicker-free even on fast refresh loops.
14+ Widgets
Block, Paragraph, List, Gauge, Table, Tabs, Sparkline, BarChart, TextInput, Spinner, Tree, Canvas, Popup, Dialog all ready to use.
Mouse Support
Full SGR mouse events on Unix and the native Console API on Windows. Click, scroll, and drag just work.
15 Built-in Themes
Nord, Dracula, Gruvbox, Catppuccin, Tokyo Night and more. Hot-swap themes at runtime with a single line.
Kitty Graphics
Display BMP images in Kitty, WezTerm and foot via the Kitty Graphics Protocol. Unicode-block fallback for other terminals.
No Hidden Allocations
All allocations go through the allocator you supply. Stack buffers, comptime sizing you stay in control of memory.
Minimal example
const std = @import("std");
const tui = @import("zigtui");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
var backend = try tui.backend.init(gpa.allocator());
defer backend.deinit();
var terminal = try tui.terminal.Terminal.init(gpa.allocator(), backend.interface());
defer terminal.deinit();
try terminal.hideCursor();
defer terminal.showCursor() catch {};
var running = true;
while (running) {
const event = try backend.interface().pollEvent(100);
if (event == .key) {
const k = event.key.code;
if (k == .esc or (k == .char and k.char == 'q'))
running = false;
}
try terminal.draw({}, struct {
fn render(_: void, buf: *tui.render.Buffer) !void {
tui.widgets.Block{
.title = "Hello ZigTUI press 'q' to quit",
.borders = tui.widgets.Borders.all(),
.border_style = .{ .fg = .cyan },
}.render(buf.getArea(), buf);
}
}.render);
}
}