TermOx II: a C++20 terminal UI library built around widgets and signals
C++20 Terminal User Interface (TUI) Library.
At a glance
- What is it?
- TermOx is a C++20 library for building interactive terminal interfaces, with a layout system driven by size policies, an event-driven core, a signal and slot mechanism taken from Signals Light, and a widget set covering labels, buttons, text inputs and data tables. Version 2 is a complete rewrite with an API that has little in common with the previous version, and the build pulls three dependencies through CMake.
- Who is it for?
- TermOx suits a C++ developer who needs a terminal interface with real widgets rather than a screen of escape sequences, and who wants the layout to be described declaratively with size policies rather than computed by hand. It does not suit a project that wants to keep an existing version 1 code base, because version 2 is a complete rewrite whose API shares little with what came before, and it does not suit someone who cannot accept a CMake build that fetches dependencies.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Widgets composed with the pipe operator
TermOx is a C++20 library for creating rich, interactive terminal user interfaces with minimal code, and the quick example shows how little code that means. A Label is created with designated initialisers for its text, alignment and brush, where the brush carries a foreground colour and the bold trait, and the border is applied with the pipe operator, with a rounded box shape and a label. The whole thing is then handed to an Application and run:
#include <ox/ox.hpp>
using namespace ox;
int main()
{
auto head = Label{{
.text = "C++20 Terminal UI Framework",
.align = Align::Center,
.brush = {.foreground = XColor::Blue, .traits = Trait::Bold},
}} | Border{.box = shape::Box::round(), .label = "TermOx II"};
return Application{head}.run();
}The pipe operator is what makes the composition read as a layout rather than as constructor calls, and the designated initialisers are what keep a widget's configuration next to its name instead of in a positional argument list. The include is a single header, ox/ox.hpp, and the namespace is brought in with a using directive. The primary language is C++, the licence is MIT, and the last push was on 2026-10-21.
Version 2 is a rewrite, not an increment
The note on version 2 is the first thing to read if you have seen the library before, and it is unambiguous. Version 2 is a complete rewrite of the library, focused on providing a simpler set of base widgets and a light-weight core implementation of events processing and rendering, and as a result the API has little in common with the previous version. That is a blunt way of saying that there is no migration path short of rewriting the interface code. The upside is what the rewrite was for. A simpler widget set and a lighter event processing and rendering core are the right goals for a terminal interface library, since the terminal is a slow canvas and the cost of the framework is paid on every frame. The trade is that you get a young API, and the repository has no GitHub releases to indicate how stable the current line is considered to be. The documentation lives in the repository itself, with a getting started page, a reference and an examples directory.
A layout system built on size policies
The core capability listed first is a flexible layout system with size policies and automatic sizing, and the second example shows what that buys you. A Row holds an IntegerLabel and a Button side by side, each with its own alignment and brush, and the button carries a press_mod lambda that changes the label's foreground colour when the button is pressed. The two children are then reached through structured binding, auto& [label, button] = counter.children, which is where the C++20 requirement earns its place beyond the designated initialisers. The alternative to this arrangement is a chain of set_position and set_size calls against absolute coordinates, which is exactly the kind of thing that breaks the moment the terminal is resized. The layout widgets listed in the feature set are horizontal, vertical and suspended layouts, and the library provides a scratch.cpp file in the examples directory together with a TermOx.examples.scratch build target so you can experiment without setting up a project of your own.
Signals and slots, and how a click reaches the label
The event system is a signal and slot mechanism based on Signals Light, and the wiring in the counter example is the part worth copying. A Connection is constructed with a signal and a slot, where the signal is the button's on_press and the slot is a lambda that increments the label's value, and the connection is then invoked with the label as the argument:
// Signals and Slots
Connection{
.signal = button.on_press,
.slot = [](IntegerLabel& l) { ++l.value; },
}(label);The signal carries the widget it came from, so the slot receives the target widget directly, and the connection object is what carries the relationship between the two. Alongside this, the core capability list names an event-driven architecture for clean handling of user input and system events, and timer support for periodic actions with timer events. For input, the library handles key press and release events with modifiers and special keys, mouse click, scroll, movement and enter or leave events, and focus management through tab navigation, mouse click and focus events. The custom widget story is that you create your own widgets with ease, which is the part that decides whether the library is a floor to build on or a ceiling.
Colour and text styling, including the 256 colour palette
The rendering side covers colours with full RGB, HSL and XTerm 256 Colour support, and text styling with bold, italic, underline, strikethrough and more. The brush abstraction is what ties the two together, since a brush carries a foreground colour and a set of traits, and the counter example shows a brush with both a background and a foreground colour plus the bold trait. The XTerm 256 colour reference is linked because that palette is a de facto standard in terminals rather than something the library invented, and the support for full RGB and HSL means the library can also express colours outside the 256 entry table. Unicode support is listed with wide character and multi-byte encoding compatibility, which is not a small detail in a terminal library, since a CJK character occupies two cells and a naive width calculation breaks every layout that contains one. The gallery in the readme shows the results for custom widgets, the library itself, colours, combinations, animation and a fractal example, which is a fair indication of what the library can draw.
The build is CMake, and it fetches its own dependencies
TermOx uses CMake to generate build targets, and the build sequence is a standard out of source CMake build:
git clone https://github.com/a-n-t-h-o-n-y/TermOx.git
mkdir TermOx/build && cd TermOx/build
cmake ..
make TermOxThe dependencies are fetched automatically by CMake, and the three of them are named: Signals Light, which is the signal and slot implementation, zzz, and and Escape. So the build needs network access on the first configure, and the third party code is what the library stands on for its event model and its terminal handling. The repository has the usual shape for a C++ project of this kind, with a CMakeLists.txt at the root, an include directory, a src directory, a tests directory, an examples directory with its own CMakeLists.txt, a docs directory and a.clang-format file for the style. The examples directory holds a scratch file for quick experiments alongside accumulator, bmp_view, pinbox, pong and snake, and the readme asks you to explore them.
What the second example shows about the widget set
The counter example is short enough to read in full, and it packs in more than it looks. The Row contains an IntegerLabel, whose value is an integer rather than text, and a Button with a text label, an alignment and a brush. The button also has a press_mod lambda, which is how a press is given a visual effect without the button having to know about the label, since the lambda captures nothing and just changes the foreground to yellow. The widgets are then wired to each other through the connection described earlier, so clicking the button changes the number the label shows. The widget library in the feature list is longer than the example: core widgets covering labels, buttons, text inputs, checkboxes, radio buttons and data tables, and layout widgets for horizontal, vertical and suspended arrangements. The data table and text input entries are the ones to look at when judging the library against a form you actually have to build, because those are the widgets where a terminal interface either works or does not.
Editorial conclusion
TermOx suits a C++ developer who needs a terminal interface with real widgets rather than a screen of escape sequences, and who wants the layout to be described declaratively with size policies rather than computed by hand. It does not suit a project that wants to keep an existing version 1 code base, because version 2 is a complete rewrite whose API shares little with what came before, and it does not suit someone who cannot accept a CMake build that fetches dependencies. Before you start, read the version 2 note, and plan for the rewrite rather than expecting a drop-in upgrade.
Frequently asked questions
What is TermOx and what does it give you over writing escape sequences by hand?
It is a C++20 library for creating rich, interactive terminal user interfaces with minimal code. It provides a flexible layout system with size policies and automatic sizing, an event-driven architecture, a signal and slot system, timer support, custom widgets, full RGB, HSL and 256 colour styling, and input handling for keyboard, mouse and focus.
How do I build TermOx?
It uses CMake to generate build targets. Clone the repository, create a build directory, run cmake there and then make TermOx. The dependencies, Signals Light, zzz and Escape, are fetched automatically by CMake during the configure step.
Can I upgrade my existing TermOx 1 code to version 2?
Not mechanically. Version 2 is a complete rewrite of the library, focused on a simpler set of base widgets and a light-weight core for event processing and rendering, and the API has little in common with the previous version. Existing interface code has to be rewritten rather than migrated.
What widgets does TermOx ship with?
Core widgets including labels, buttons, text inputs, checkboxes, radio buttons and data tables, plus horizontal, vertical and suspended layouts. There is also an IntegerLabel for numeric display and a scratch example file with a matching build target so you can try the library quickly.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/a-n-t-h-o-n-y-termox)Was this useful?