Havoc's single-file terminal utility library for modern C and C++.
It provides ANSI escape macros for text styling, colors, cursor control, screen clearing, and hyperlinks, plus helper functions for Windows VT / UTF-8 setup and VT input / mouse handling.
- Features
- Showcase Project
- Quick Start
- Minimal C Example
- Minimal C++ Example
- VT Mouse Example
- Basic API
- Contributing
- License
- Header-only (
havTermKit.h) - Works with C and C++
- ANSI text styles: bold, underline, italic, reverse, hidden, blink, strike, reset variants
- 16-color foreground / background palettes (normal + bright)
- 256-color and true color helper macros
- Cursor movement, save / restore, clear line / screen macros
- OSC hyperlink macros
- Initialization helpers for Windows VT processing + UTF-8 console setup
- VT input helpers: input mode toggles, cursor show / hide, mouse tracking on / off, blocking / non-blocking byte read, SGR mouse parse
- Realtime input helper for non-Windows platforms: raw and non-blocking stdin mode
- Terminal mode helpers: alternate screen enter / leave and line wrap enable / disable
- Terminal size helper: query current columns / rows
havTermViper: Havoc's terminal game and the official showcase project for havTermKit.
Requires a C99+ compiler (or any modern C++ compiler).
- Copy
havTermKit.hinto your project. - Include the header:
#include "havTermKit.h"- Call init once at startup:
havTermKit_Init();Note
On non-Windows platforms, havTermKit_Init() is a no-op.
- Use the provided macros in output:
printf(ANSI_FG_BRIGHT_GREEN "Success" ANSI_RESET "\n");
printf(ANSI_UNDERLINE "Underlined text" ANSI_RESET "\n");Important
On Windows:
havTermKit.hrequires Unicode (UNICODEand_UNICODEdefined,_MBCSnot defined)havTermKit_Init()enables VT processing and configures the console code page to UTF-8
Note
ANSI_BLINK is included, but blink rendering depends on terminal support.
#include <stdio.h>
#include "havTermKit.h"
int main(void)
{
havTermKit_Init();
printf(ANSI_FG_BRIGHT_GREEN "\u2714 Success" ANSI_RESET "\n");
printf(ANSI_FG_BRIGHT_RED "\u2716 Error" ANSI_RESET "\n");
printf(ANSI_UNDERLINE "Underlined text" ANSI_RESET "\n");
printf(ANSI_LINK_START("https://test.com") "Open test.com" ANSI_LINK_END "\n");
return 0;
}Linux / macOS (GCC / Clang):
gcc main.c -o app
./appWindows (GCC in PowerShell / CMD):
gcc -DUNICODE -D_UNICODE main.c -o app.exe
app.exe#include <iostream>
#include "havTermKit.h"
int main()
{
havTermKit_Init();
std::cout << ANSI_FG_BRIGHT_GREEN << "\u2714 Success" << ANSI_RESET << "\n";
std::cout << ANSI_FG_BRIGHT_RED << "\u2716 Error" << ANSI_RESET << "\n";
std::cout << ANSI_UNDERLINE << "Underlined text" << ANSI_RESET << "\n";
std::cout << ANSI_LINK_START("https://test.com") << "Open test.com" << ANSI_LINK_END << "\n";
return 0;
}Linux / macOS (G++ / Clang++):
g++ main.cpp -o app
./appWindows (G++ in PowerShell / CMD):
g++ -DUNICODE -D_UNICODE main.cpp -o app.exe
app.exehavTermKit includes VT mouse helpers for SGR mouse sequences (ESC [ < b ; x ; y M/m), including enable / disable tracking and parsing.
#include <stdio.h>
#include <stdint.h>
#include "havTermKit.h"
int main(void)
{
havTermKit_Init();
havTermKit_EnableInputVT(); // Needed on Windows for VT input
havTermKit_EnableRawInputNonBlocking(); // Needed on non-Windows platforms for realtime byte input
havTermKit_MouseEnable();
printf("Move / click mouse. Press q to quit.\n");
while (true)
{
uint8_t c = 0;
if (!havTermKit_TryReadByte(&c))
{
continue;
}
if (c == 'q' || c == 'Q')
{
break;
}
if (c == 0x1b)
{
havTermKit_MouseEvent ev;
if (havTermKit_ParseSgrMouseAfterEsc(&ev))
{
printf("mouse: x=%d y=%d pressed=%d code=%d\n", ev.x, ev.y, ev.pressed ? 1 : 0, ev.code);
}
}
}
havTermKit_RestoreConsole();
return 0;
}Linux / macOS (GCC / Clang):
gcc mouse.c -o mouseApp
./mouseAppWindows (GCC in PowerShell / CMD):
gcc -DUNICODE -D_UNICODE mouse.c -o mouseApp.exe
mouseApp.exeNote
VT mouse behavior depends on terminal support. On Windows, this works best in Windows Terminal / ConPTY-aware hosts.
havTermKit_Init()havTermKit_EnableInputVT()(returnsfalseif VT input setup is unavailable / fails)havTermKit_DisableInputVT()(best-effort restore of cooked input mode on Windows)havTermKit_EnableRawInputNonBlocking()(returnsfalseif raw / non-blocking setup fails on non-Windows platforms)havTermKit_DisableRawInputNonBlocking()(restores stdin mode on non-Windows platforms)havTermKit_RestoreConsole()(best-effort cleanup for mouse and input modes)havTermKit_GetTerminalSize(&cols, &rows)(returnstrueon success)havTermKit_AlternateScreenEnter(),havTermKit_AlternateScreenLeave()havTermKit_WrapEnable(),havTermKit_WrapDisable()
havTermKit_MouseEventhavTermKit_CursorHide(),havTermKit_CursorShow(),havTermKit_CursorHome()havTermKit_MoveTo(row, col)(clampsrowandcolto at least1),havTermKit_ClearScreen()havTermKit_MouseEnable(),havTermKit_MouseDisable()havTermKit_ReadByte(&b)havTermKit_TryReadByte(&b)havTermKit_ParseSgrMouseAfterEsc(&mouseEvent)
havTermKit_ReadByte(&b)is blockinghavTermKit_TryReadByte(&b)is non-blocking and returnsfalsewhen no byte is availablehavTermKit_TryReadByte(&b)returns raw input bytes; decoding escape / extended key sequences is application-specific
- Reset:
ANSI_RESET - Styles:
ANSI_BOLD,ANSI_UNDERLINE,ANSI_ITALIC,ANSI_STRIKETHROUGH, etc. - Foreground colors:
ANSI_FG_RED,ANSI_FG_BRIGHT_CYAN, etc. - Background colors:
ANSI_BG_BLUE,ANSI_BG_BRIGHT_YELLOW, etc. - 256 colors:
ANSI_FG_256("196"),ANSI_BG_256("27") - RGB colors:
ANSI_FG_RGB("255","120","0"),ANSI_BG_RGB("20","20","20") - Cursor / screen:
ANSI_CURSOR_UP("2"),ANSI_CLEAR_LINE,ANSI_CLEAR_SCREEN - Cursor visibility / positioning / clear-home:
ANSI_CURSOR_HIDE,ANSI_CURSOR_SHOW,ANSI_CURSOR_HOME,ANSI_CLEAR_SCREEN_HOME - Screen mode toggles:
ANSI_ALTERNATE_SCREEN_ENTER,ANSI_ALTERNATE_SCREEN_LEAVE,ANSI_WRAP_ENABLE,ANSI_WRAP_DISABLE - VT mouse tracking:
ANSI_MOUSE_ENABLE,ANSI_MOUSE_DISABLE - Hyperlinks:
ANSI_LINK_START("https://test.com") "Open test.com" ANSI_LINK_END
Thank you for your interest! Suggestions for features and bug reports are always welcome via issues.
To maintain a consistent design and quality for this library, changes are implemented by the maintainer rather than via direct pull requests.
Copyright © 2026 René Nicolaus
This library is released under the MIT license.
