cpp-terminal: a small cross-platform C++ library for terminal applications
C++ library for writing multiplatform terminal applications
At a glance
- What is it?
- CPP-Terminal is a dependency-free C++ library for writing terminal applications that behave the same on Windows, Linux and MacOS, with colors, keyboard input and resize handling and nothing beyond the C++ STL. Its narrow feature set is deliberate, and the README is direct about the platforms it cannot cover.
- Who is it for?
- Use CPP-Terminal when you are writing a terminal program in C++ and want one code path across Windows, Linux and MacOS without pulling in a curses library, and when the features you need are limited to colors, keys, prompts and a managed window. Do not use it if you need widgets, mouse handling, or styling that differs per platform, since the library deliberately restricts itself to a subset that behaves identically everywhere.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 4 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
The zero-overhead principle means STL only, nothing else
CPP-Terminal describes itself as a small and dependency-free C++ library for writing platform independent terminal-based applications. The mechanism behind that claim is a rule about what may be included: the library limits externally included files to the C++ STL, and calls this the "Zero-overhead principle".
That constraint is the whole design. A terminal library that reaches for platform SDKs directly still has to paper over the differences between Windows console handling, POSIX termios and the MacOS terminal, and that is where the weight usually comes from. By confining itself to what the standard library offers and implementing the platform-specific work behind its own API, the library can claim a unified API across all platforms.
The claimed features are narrow and concrete: colors, keyboard input, terminal resize handling, and other common terminal functionality. The library also notes it is possible to open a managed terminal from a Windows GUI application, which is a real capability on that platform, since a Windows GUI process has no console of its own to write to.
The tradeoff is scope. The library states that it limits itself to a subset of features that work on all supported platforms without worrying about style differences or other changes, so an application written with it works everywhere natively, without emulation.
The single header was split into four usage-oriented headers
Until 2021, CPP-Terminal was a single header library. It now consists of multiple small, usage-oriented headers, and the README names four of them explicitly. `cpp-terminal/input.hpp` holds the functions for gathering input. `cpp-terminal/prompt.hpp` provides some variations of different prompts. `cpp-terminal/window.hpp` provides a fully managed terminal window for terminal user interfaces. `cpp-terminal/version.hpp` exposes macros carrying the library's version number.
This restructuring tells you what the library considers its main modes of use. There is a low-level path where you call functions yourself, a prompt path for interactive line editing, and a windowing path where the library owns the screen and handles input and resize events for you. The examples directory mirrors that structure, with separate files for prompts (`prompt_simple.cpp`, `prompt_immediate.cpp`, `prompt_multiline.cpp`, `prompt_not_immediate.cpp`), for the managed window (`menu_window.cpp`), and for a hand-rolled menu built from `cpp-terminal/base.hpp` alone.
The `version.hpp` header is worth noting for a practical reason. A version macro in a public header lets a consuming project assert at compile time which release of the library it was built against, which matters for a library with no GitHub releases attached to its tags.
Including terminal.hpp is enough to turn on color output
The README's first Hello World example is deliberately minimal. The program includes one header and writes a string containing an ANSI escape sequence:
#include "cpp-terminal/terminal.hpp"
#include <iostream>
int main()
{
std::cout << "Just including terminal.hpp activate \033[31mcolor\033[0m !" << std::endl;
}The point of the example is the side effect. The comment in the program says that including terminal.hpp activates color, which means the header performs terminal initialization on inclusion rather than requiring an explicit setup call. That is convenient for small programs and it is also a hidden dependency on global state, so a project with its own initialization order should know about it before the first build fails in a confusing way.
The second example does the same thing through the library's own API instead of raw escape codes, adding `cpp-terminal/color.hpp` and wrapping the text in `Term::color_fg` calls with `Term::Color::Name::Red` and `Term::Color::Name::Default`:
#include "cpp-terminal/terminal.hpp"
#include "cpp-terminal/color.hpp"
#include <iostream>
int main()
{
std::cout << Term::color_fg(Term::Color::Name::Red)<<"Hello world !"<<color_fg(Term::Color::Name::Default)<< std::endl;
}Both examples are complete programs with a `main` and no arguments, so they can be compiled and run as they are.
Attaching a console from a Windows GUI application
On Windows, a graphical application starts without a console, so writing to standard output does nothing useful. The README shows the fix, and it is a different entry point rather than a different library: a `WinMain` function instead of `main`, with `<windows.h>` included alongside the terminal headers.
#include "cpp-terminal/terminal.hpp"
#include "cpp-terminal/color.hpp"
#include <iostream>
#include <windows.h>
int __stdcall WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, int show)
{
std::cout << Term::color_fg(Term::Color::Name::Red)<<"Hello world !"<<color_fg(Term::Color::Name::Default)<< std::endl;
return 0;
}The example directory makes this a first-class case rather than a footnote. There are two files for it, `attach_console.cpp` and `attach_console_minimal.cpp`, and the README's opening sentence about opening a managed terminal from a Windows GUI application refers to this capability.
The point for a reader evaluating the library is that a Windows GUI program does not need a second output mechanism. The same color API works in the console that the application attaches, so a tool that is a GUI on Windows and a terminal program elsewhere can share its output code, provided the platform-specific entry point is isolated in one place.
The platform matrix stops at Windows 10 because of raw mode
The support table is unusually detailed, and the most important entry is the footnote. Windows versions prior to Windows 10 are missing the Win32 API functionality for entering the "raw mode", so they will not work, and they also lack ANSI support. The README points to issue #173 for adding support to prior versions.
That single limitation shapes the platform story. The table lists Windows 10 and higher with x86 and x86_64 architectures, compiled with MSVC 2019, MSVC 2022, clang11 through clang15 and clang-cl, against C++ standards 11, 14, 17 and 20. MSYS2 is listed separately with all supported versions and the ucrt, clang and mingw toolchains. MacOS 11 and 12 are covered with a list of xcode and gcc versions, and Linux with GCC from 4.7 up to 12, Clang from 3.5 up to 15 and intel-oneapi, all at the same four C++ standards.
A cross-platform C++ library that supports C++11 and C++20, four GCC generations and both MSVC and clang on Windows is a wide matrix to claim, and the raw mode footnote shows where the claim ends. Keyboard input is the feature that depends on raw mode, so a program that reads individual keypresses rather than lines is the part that cannot run on pre-10 Windows, while a program that only prints colored output could still work.
The dockcross row extends the Linux claim to many embedded targets, including armv5, armv6, armv7a, mips, mipsel-lts, s390x, ppc64le, xtensa-uclibc, x64-tinycc and others, with the same compiler range.
Examples cover colors, keys, prompts, cursor and a ported text editor
The examples directory is the best documentation in the repository, and the README names the five it highlights. `colors.cpp` is a basic color, style and unicode demo. `kilo.cpp` is the kilo text editor ported to C++ and CPP-Terminal instead of using Linux specific API. `menu.cpp` is an interactive menu using only the contents of `cpp-terminal/base.hpp`. `menu_window.cpp` is an interactive menu using the fully managed windowing system from `cpp-terminal/window.hpp`. `keys.cpp` interactively shows the keys pressed.
The kilo example deserves attention because it is the honest test of a terminal library. A text editor needs raw key input, cursor positioning, screen clearing and redraw on resize, all of which are exactly the features that are hard to make portable. The README notes that every example works natively on all platforms in the exact same way, which is the claim that matters for a library whose purpose is to avoid per-platform code.
The full listing of the examples directory is longer than the five highlighted ones and reads like a feature checklist: `args.cpp`, `cin_cooked.cpp`, `cin_raw.cpp`, `cout.cpp`, `cursor.cpp`, `events.cpp`, `minimal.cpp`, `signal.cpp`, `styles.cpp` and `utf8.cpp` sit alongside the prompt and menu files. Cooked versus raw console input appears as a pair of examples, which is a useful signal that the library exposes that distinction explicitly.
CPP-Terminal against ncurses, and what the restricted subset costs
The README states the ambition plainly: CPP-Terminal tries to be a small and simple replacement for ncurses. The approach it contrasts with is curses-style portability, where a large library implements a widget toolkit and a styling language and a terminal program depends on that abstraction.
The difference in approach is that CPP-Terminal hands you a small set of primitives and lets you build the interface yourself, where ncurses hands you the interface. The library argues that this keeps the code small and maintainable, easy to extend, easy to debug, and understandable down to the core, and that a small codebase is what makes the platform behavior predictable. Its answer to ncurses-style styling differences is not to emulate them but to avoid them, by limiting itself to a subset that behaves the same everywhere.
The cost is equally clear. There is no widget set, no layout manager and no theming layer, so a full screen application means writing the drawing and event loop code yourself. The `menu_window.cpp` and `menu.cpp` examples show both routes, one built on the managed window and one built from `cpp-terminal/base.hpp`, and the difference in effort between them is the difference the library is asking you to make.
The maintenance picture is favorable but not finished. The repository is not archived, the last push was on 2026-10-19, and the README carries Linux, Windows, MacOS, docs, CodeQL and pre-commit CI badges. The repository has no GitHub releases, so version tracking relies on the `version.hpp` macros and the git tags rather than a published release list, and the licence is reported as Other, a custom licence that GitHub cannot classify, with the terms in the LICENSE file.
Editorial conclusion
Use CPP-Terminal when you are writing a terminal program in C++ and want one code path across Windows, Linux and MacOS without pulling in a curses library, and when the features you need are limited to colors, keys, prompts and a managed window. Do not use it if you need widgets, mouse handling, or styling that differs per platform, since the library deliberately restricts itself to a subset that behaves identically everywhere. Before you commit, confirm your minimum target is Windows 10 or later, because earlier versions lack the Win32 raw mode support and ANSI handling the library depends on.
Frequently asked questions
What is cpp-terminal and what does it replace?
CPP-Terminal is a small, dependency-free C++ library for writing platform independent terminal applications, and the README says it tries to be a small and simple replacement for ncurses. It limits externally included files to the C++ STL and supports Windows, Linux and MacOS with a unified API.
Which Windows versions does cpp-terminal support?
Windows 10 and higher are supported, with x86 and x86_64 architectures. Versions prior to Windows 10 are missing the Win32 API functionality for entering raw mode and also lack ANSI support, so they will not work; the README points to issue #173 for that gap.
How do I print colored text with cpp-terminal?
The README's example includes `cpp-terminal/terminal.hpp` and `cpp-terminal/color.hpp`, then writes `Term::color_fg(Term::Color::Name::Red)` and resets with `Term::Color::Name::Default`. Including terminal.hpp is enough to activate color output on its own.
Does cpp-terminal provide a managed terminal window for TUIs?
Yes. The header `cpp-terminal/window.hpp` provides a fully managed terminal window for terminal user interfaces, and the `menu_window.cpp` example builds an interactive menu with it. A lighter alternative is `cpp-terminal/base.hpp`, which the `menu.cpp` example uses on its own.
Which headers does cpp-terminal provide and what are they for?
The README names four: `cpp-terminal/input.hpp` for gathering input, `cpp-terminal/prompt.hpp` for prompt variations, `cpp-terminal/window.hpp` for a fully managed terminal window, and `cpp-terminal/version.hpp` for macros carrying the version number. The library used to be a single header until 2021.
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/jupyter-xeus-cpp-terminal)Was this useful?