C++26 TUI framework with type-state compile-time DSL, Yoga flexbox,
SIMD cell-diff renderer, and Elm-style runtime.
Quickstart · Examples · Widgets · Docs · Building
- Compile-time UI trees.
t<"Hello"> | Bold | border_<Round>is type-state safe — try to set border color without a border and it's a compile error, not a runtime no-op. - SIMD frame diff. AVX2 / SSE4.2 / NEON. 64-bit packed cells, O(1) compare. Only changed cells write to the terminal.
- Real flexbox. Yoga layout —
grow(),gap(),align(),justify(). Noprintfcolumn-counting. - Two render modes. Fullscreen (alternate screen) or inline (lives in your scrollback, doesn't take over the terminal).
- Two app APIs.
run(event_fn, render_fn)for quick tools;run<Program>()Elm-style for testable pure logic with algebraic effects. - Header-mostly.
#include <maya/maya.hpp>is the public surface. Widgets opt-in individually.
Static UI — fully resolved at compile time:
#include <maya/maya.hpp>
using namespace maya::dsl;
int main() {
constexpr auto ui = v(
t<"Hello World"> | Bold | Fg<100, 180, 255>,
h(
t<"Status:"> | Dim,
t<"Online"> | Bold | Fg<80, 220, 120>
) | border_<Round> | bcol<50, 55, 70> | pad<1>
);
maya::print(ui.build());
}Interactive counter — quick-tool API:
Signal<int> count{0};
run({.title = "counter"},
[&](const Event& ev) {
if (key(ev, '+')) count.update([](int& n) { ++n; });
if (key(ev, '-')) count.update([](int& n) { --n; });
return !key(ev, 'q');
},
[&] {
return v(
text("Count: " + std::to_string(count.get())) | Bold | Fg<100, 200, 255>,
t<"[+/-] change [q] quit"> | Dim
) | border_<Round> | bcol<50, 55, 70> | pad<1>;
}
);Same counter — Elm-style Program for testable pure logic:
struct Counter {
struct Model { int count = 0; };
struct Inc {}; struct Dec {}; struct Quit {};
using Msg = std::variant<Inc, Dec, Quit>;
static Model init() { return {}; }
static auto update(Model m, Msg msg) -> std::pair<Model, Cmd<Msg>> {
return std::visit(overload{
[&](Inc) { return std::pair{Model{m.count + 1}, Cmd<Msg>{}}; },
[&](Dec) { return std::pair{Model{m.count - 1}, Cmd<Msg>{}}; },
[](Quit) { return std::pair{Model{}, Cmd<Msg>::quit()}; },
}, msg);
}
static Element view(const Model& m) {
return v(text(m.count) | Bold, t<"[+/-] q quit"> | Dim) | pad<1> | border_<Round>;
}
static auto subscribe(const Model&) -> Sub<Msg> {
return key_map<Msg>({{'+', Inc{}}, {'-', Dec{}}, {'q', Quit{}}});
}
};
int main() { run<Counter>({.title = "counter"}); }26 examples ship with the framework:
Plus FPS raycaster, raymarcher, fluid sim, mandelbrot zoom, matrix rain, particle systems, spectrum analyzer, breakout, snake, music player, system monitor, AI agent demos, and more. All under examples/.
moha — a native terminal client for Claude — is built on maya in production.
Data: Line chart · Bar chart · Gauge · Sparkline · Heatmap · Flame chart · Waterfall · Token stream · Context window · Git graph
Input: Text input · Textarea · Select · Slider · Checkbox · Radio · Button · Menu · Command palette
Layout: Table · Tabs · Tree · Scrollable · Modal · Popup · Toast · Disclosure · Divider · Breadcrumb
Display: Markdown · Inline diff · Diff view · Badge · Spinner · Progress bar · Calendar · Canvas · Image · Log viewer
Agent UI: Tool call · Bash tool · Read tool · Edit tool · Write tool · Fetch tool · Message · Thinking block · Streaming cursor · Activity bar · Permission prompt · Model badge · Cost tracker · Git status · File changes · System banner · Error block · Turn divider · Conversation view · Plan view · API usage
- Elm-style
Programconcept:Model+Msg+init/update/view/subscribe. - Effects as data:
Cmd<Msg>(quit,batch,after,task) andSub<Msg>(keys, mouse, timers). - Signal / slot reactivity (SolidJS-inspired).
- Type-state render pipeline: Idle → Cleared → Painted → Opened → Closed.
- Keyboard, mouse, resize, focus/blur, and bracketed-paste events out of the box.
#include <maya/maya.hpp> // DSL, run<P>(), events, signals, styles — public API
#include <maya/widget/input.hpp> // widgets included individually
#include <maya/internal.hpp> // canvas, diff engine, SIMD, terminal I/O (unstable)| Header | Contains | Stability |
|---|---|---|
maya.hpp |
DSL, Program, Cmd, Sub, events, signals, styles, elements, themes | Stable |
widget/*.hpp |
69 widgets | Stable |
internal.hpp |
Canvas, diff, renderer, SIMD, terminal I/O, layout | Internal |
Requires C++26. GCC 15+ recommended on all platforms.
# Arch
sudo pacman -S gcc cmake
cmake -B build && cmake --build build -j$(nproc)
# Ubuntu/Debian
sudo apt install g++-15 cmake
cmake -B build -DCMAKE_CXX_COMPILER=g++-15
cmake --build build -j$(nproc)
# Fedora
sudo dnf install gcc-c++ cmake
cmake -B build && cmake --build build -j$(nproc)AppleClang doesn't support C++26. Use Homebrew GCC:
brew install gcc@15 cmake
cmake -B build -DCMAKE_CXX_COMPILER=g++-15
cmake --build build -j$(sysctl -n hw.ncpu)MSYS2 (recommended):
pacman -S mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-cmake
cmake -B build -G "MinGW Makefiles"
cmake --build build -j%NUMBER_OF_PROCESSORS%Visual Studio 2025+:
cmake -B build -G "Visual Studio 17 2025"
cmake --build build --config ReleaseWSL2: follow the Linux instructions.
cmake -B build -DMAYA_BUILD_TESTS=ON
cmake --build build
ctest --test-dir buildcmake --install build --prefix /usr/localfind_package(maya 0.1 REQUIRED)
target_link_libraries(my_app PRIVATE maya::maya)#include <maya/maya.hpp>
#include <maya/widget/markdown.hpp>MIT.




