C++26 terminal UI framework.
Compile-time DSL. Flexbox layout. SIMD rendering. 69 widgets. Cross-platform.
Quickstart · Examples · Features · Docs · Building
Build terminal apps that look good and run fast. Maya gives you a type-safe DSL that catches layout mistakes at compile time, a flexbox engine for real layout, and a rendering pipeline that diffs frames with SIMD so only changed cells hit the terminal.
Ships with 69 widgets — from inputs and tables to markdown renderers, tool call cards, and everything you need to build an AI agent interface. Runs on Linux, macOS, and Windows.
Static UI:
#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:
#include <maya/maya.hpp>
using namespace maya;
using namespace maya::dsl;
int main() {
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>;
}
);
}Elm architecture for complex apps:
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"}); }Two APIs, same runtime. run(event_fn, render_fn) for quick tools. run<P>() when you want testable pure logic and algebraic effects.
26 examples ship with the framework:
Also: FPS raycaster, raymarcher, fluid simulation, mandelbrot zoom, matrix rain, particle systems, sorting visualizations, spectrum analyzer, breakout, snake, space shooter, music player, system monitor, AI agent simulation, and more. All under examples/.
- Compile-time UI trees with
|pipe operators - Type-state safety — can't set border color without a border, can't apply layout to text
t<"...">for compile-time text,text()for runtime- Composes naturally:
v(),h(),text(),border_<>,pad<>,Fg<>,Bold
- Flexbox via Yoga —
grow(),gap(),width(),height(),align(),justify() - Fullscreen and inline rendering modes (alternate screen or native scrollback)
- Double-buffered with dirty-region tracking
- SIMD-accelerated frame diff (AVX2 / SSE4.2 / NEON) — only changed cells write to terminal
- 64-bit packed cells for O(1) comparison
- Cache-line aligned buffers, style interning via open-addressing hash map
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) - Type-state render pipeline (Idle → Cleared → Painted → Opened → Closed)
- Signal/slot reactivity (SolidJS-inspired)
- Keyboard, mouse, resize, focus/blur, paste events
#include <maya/maya.hpp> // DSL, run<P>(), events, signals, styles — the public API
#include <maya/widget/input.hpp> // widgets are 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




