Skip to content

gbuiA UI toolkit for C++

Flexbox layout, 63 themeable components and a painter you can implement — no web engine, no runtime, nothing to fetch.

This is it, running

Compiling nothing — this is C++, already compiled.

A real application screen, drawn by the same source that builds a desktop binary. There is no DOM inside that rectangle, no elements and no CSS — what you are pointing at is a display list, rasterised on the CPU. Switch the design system above and watch it re-shape without a rebuild.

Everything in it

Why it is built this way

Layout you already know. Rows, columns, grow and shrink, gaps, padding, wrapping, percentages, min-content sizing — the CSS flexbox model, because that is the model desktop UIs are written in today.

Themes as data. 24 semantic tokens from a JSON file, and a Design beside them for shape, sizing and motion. A component names tokens, never colours, so a whole application re-themes without being rebuilt — which is what the buttons above the screen are doing.

Testable without a screen. Layout is arithmetic and painting is a display list, so both are asserted in CI with no window, no GPU and no font installed. 391 tests, and every demo screen rendered headless on every push.

One allocation per frame. Nodes live in an arena addressed by index. Building a tree is a push_back, releasing one is a reset, and the same pages are reused every frame.

Bring your own painter. Six methods make a backend. A software rasteriser and an SVG writer ship with the library; a GPU one is the same six methods.

Vector everything. An SVG path parser, 40 Lucide glyphs and a canvas node, so icons, commit graphs and charts are geometry rather than bitmaps — sharp at any scale, in the theme's colours.

Every control says what it is. A role, a name, a state, and the relations that tie a caption to its field, on every component — read into a pruned accessibility tree that is diffed each frame, so a screen reader is told what changed rather than everything. Two gates in CI keep it true of the library and of the applications built on it.

Twelve lines

cpp
#include "gbui/widgets/elements.hpp"

auto column = ui.column({.gap = 8.0f, .padding = Edges::all(12.0f)});
text(ui, "Local Changes", {.color = Token::TextStrong});

if (checkbox(ui, input, "settings.tags", showTags, {.label = "Show tags"}))
    showTags = !showTags;

if (button(ui, input, "COMMIT", {.variant = ButtonVariant::Primary}))
    commit();

No base class, no inheritance, no signals and no code generator. A component is a function that takes a Ui& and an options struct, and holds no state — the value is yours, which is what makes undo, validation and "are you sure?" possible without the toolkit knowing about any of them.

Your first window · How it is put together · Seven full screens · Download a build

Released under the LGPL-3.0-or-later licence.