DEV Community

Ahmed Mohyeldin
Ahmed Mohyeldin

Posted on

Introducing ConVTS: a C/C++ Library for Modern Terminal Applications

I just released ConVTS v0.9.0-beta, a zero-dependency C/C++ library for building modern console and CLI applications.

ConVTS provides ANSI/VT sequence generation, command execution helpers, raw terminal input, keyboard parsing, mouse parsing, terminal dimensions, and terminal state handling.

GitHub: https://github.com/MohyeldinX/ConVTS

Intro video: https://youtu.be/vM7oZJfklX0?si=fLOTEOacFUjKx4Qk

This is a public beta, and I would really appreciate feedback from C, C++, systems, tooling, terminal, and CLI developers before the 1.0 release.

Why I built it

Terminal control in C and C++ often lives in an awkward place.

At one end, you can manually write escape sequences like "\x1b[31m" and hope the code stays readable. At the other end, you can use a larger UI framework that may be more than you need for a small CLI tool, teaching example, terminal demo, or lightweight TUI.

I wanted something in the middle:

  • Small enough to understand.
  • Direct enough for C and C++ courses.
  • Useful enough for professional CLI tools.
  • Cross-platform.
  • Zero-dependency.
  • Available as both header-only and compiled library.
  • Friendly to C, but with clean C++ wrappers.

That became ConVTS, short for Console Virtual Terminal Sequences Support Library.

The library is organized into three main modules:

  • ConVTS-SEQ: generate ANSI/VT escape sequence strings.
  • ConVTS-CMD: execute terminal commands by writing sequences to stdout.
  • ConVTS-IO: handle raw mode, keyboard input, mouse input, terminal dimensions, and terminal state.

Header-only usage

ConVTS can be used in an STB-style header-only mode.

Define CONVTS_IMPLEMENTATION in exactly one source file before including the umbrella header:

#define CONVTS_IMPLEMENTATION
#include <stdio.h>
#include <convts/convts.h>

int main(void) {
    vts_cmd_screen_clear();
    vts_cmd_cursor_move_home();

    vts_cmd_style_set_fg_16(VTS_COLOR_GREEN);
    vts_cmd_style_set_bold();

    puts("Hello from ConVTS");

    vts_cmd_style_reset();
    vts_cmd_flush();

    return 0;
}
Enter fullscreen mode Exit fullscreen mode

In larger projects, only one .c or .cpp file should define CONVTS_IMPLEMENTATION. Other files should include the header normally:

#include <convts/convts.h>
Enter fullscreen mode Exit fullscreen mode

This mode is useful for small tools, examples, experiments, courses, and projects where you want simple integration.

Compiled-library usage

ConVTS can also be built as a static or shared library.

In that mode, your application does not define CONVTS_IMPLEMENTATION. It just includes the header and links against the compiled target.

Example:

#include <stdio.h>
#include <convts/convts.h>

int main(void) {
    vts_cmd_screen_clear();
    vts_cmd_cursor_move_home();

    vts_cmd_style_set_fg_16(VTS_COLOR_CYAN);
    puts("Hello from a compiled ConVTS build.");

    vts_cmd_style_reset();
    vts_cmd_flush();

    return 0;
}
Enter fullscreen mode Exit fullscreen mode

With CMake:

find_package(convts REQUIRED)

add_executable(my_app main.c)
target_link_libraries(my_app PRIVATE convts::convts)
Enter fullscreen mode Exit fullscreen mode

This mode is better for larger applications, shared codebases, packaging, installation, and normal library consumption.

C and C++ API comparison

The C API is the main API. It is flat, explicit, and predictable:

vts_cmd_screen_clear();
vts_cmd_cursor_move_home();
vts_cmd_style_set_fg_16(VTS_COLOR_GREEN);
vts_cmd_style_set_bold();

puts("Hello from C");

vts_cmd_style_reset();
vts_cmd_flush();
Enter fullscreen mode Exit fullscreen mode

The C++ wrappers map directly to the same behavior using namespaces:

#include <cstdio>
#include <convts/convts.h>

int main() {
    vts::cmd::screen::clear();
    vts::cmd::cursor::move_home();

    vts::cmd::style::set_fg_16(VTS_COLOR_GREEN);
    vts::cmd::style::set_bold();

    std::puts("Hello from C++");

    vts::cmd::style::reset();
    vts::cmd::flush();

    return 0;
}
Enter fullscreen mode Exit fullscreen mode

The goal is not to hide the terminal model behind a large abstraction. The goal is to make the terminal model easier, safer, and more readable while keeping the code close to what is actually happening.

SEQ vs CMD

ConVTS separates sequence generation from command execution.

If you want to generate an escape sequence string without writing it immediately, use SEQ:

const char* seq = vts_style_set_fg_16(VTS_COLOR_RED);
fputs(seq, stdout);
Enter fullscreen mode Exit fullscreen mode

If you want to execute the command directly, use CMD:

vts_cmd_style_set_fg_16(VTS_COLOR_RED);
Enter fullscreen mode Exit fullscreen mode

This keeps both low-level and high-level workflows available.

Library authors, renderers, and buffered systems may prefer SEQ. Application code and demos may prefer CMD.

Console input and terminal state

ConVTS also includes input and state helpers through ConVTS-IO.

The IO module supports features such as:

  • Raw mode.
  • Terminal size queries.
  • Keyboard input parsing.
  • Mouse input parsing.
  • Input-buffer helpers.
  • Terminal setup and cleanup workflows.

This is useful when building interactive CLI tools, small terminal games, input demos, dashboards, and text-based interfaces.

Examples included

The repository includes several examples:

  • hello_world
  • hello_world_compiled
  • dashboard
  • sandbox
  • snake
  • demo_io

Most examples are written to demonstrate header-only usage clearly. The hello_world_compiled example demonstrates linking against ConVTS as a compiled library.

The purpose of the examples is not only testing. They are also meant to teach users how to integrate the library in real projects.

Documentation and build support

The repository includes:

  • README.md for the project overview.
  • BUILDING.md for CMake, installation, and integration.
  • CONTRIBUTING.md for contribution workflow.
  • DEVELOPER.md for architecture, naming, formatting, and development rules.
  • Generated Doxygen API documentation under docs/api/html.

ConVTS currently supports C99 and C++11, and the CI matrix builds and tests the project across header-only, static library, and shared library modes.

What I want feedback on before 1.0

This is a beta release, so I am especially interested in feedback on:

  • API naming.
  • C API usability.
  • C++ wrapper naming and ergonomics.
  • CMake integration.
  • Documentation clarity.
  • Missing examples.
  • Terminal compatibility.
  • Raw input and mouse behavior.
  • Anything that would make the library easier to teach or adopt.

If you work with C, C++, CLI tools, terminal applications, or teaching systems programming, I would really appreciate your thoughts.

GitHub: https://github.com/MohyeldinX/ConVTS

Intro video: https://youtu.be/vM7oZJfklX0?si=ig0T95ArrTMsTaJI

Top comments (0)