Getting started
ckVision is a C++20 terminal UI library. Link the ckvision::cvision target,
construct an ui::Application from a terminal and clock supplied by the host,
build a view tree, then let Application::run() own the ordinary interactive
loop. The examples are the most useful starting point because they are built,
tested, and screenshot from the exact same object graphs documented here.
Build the library and examples
You need a C++20 compiler, CMake 3.25 or later, and Python 3. A top-level
configure builds the test suite by default, and its gates run Python scripts,
so CMake stops without a Python 3 interpreter. To build only the library and
the examples, configure with -DCKVISION_BUILD_TESTING=OFF, which needs no
Python.
Warnings are errors by default. The zero-warning build is checked with GCC 13
and GCC 14 on Linux, AppleClang on macOS and MSVC on Windows; a newer compiler
that adds a diagnostic builds with -DCKVISION_WARNINGS_AS_ERRORS=OFF.
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j8
./build/examples/ckvision_hello
Install and consume the package
Install a built tree to a chosen prefix. The framework headers and CMake
package are always installed. When examples are enabled, the runnable examples
are installed in bin/, including ckvision_terminal.
cmake --install build --prefix "$PWD/ckvision-install"
./ckvision-install/bin/ckvision_editor_profile_sample
An application consuming that installation links the public target:
find_package(ckvision CONFIG REQUIRED)
target_link_libraries(my_app PRIVATE ckvision::cvision)
For a local prefix, configure the client with
-DCMAKE_PREFIX_PATH=/absolute/path/to/ckvision-install. The
install_package_smoke CTest gate stages an installation, builds a separate
consumer through this exact find_package path, and runs it.
On macOS and Linux, the shipped POSIX terminal and clock are the normal host
adapters. On every platform, HeadlessTerminal and ManualClock provide a
deterministic test host. Do not let widgets read the clock, terminal, clipboard
or filesystem themselves: pass services through Application or the relevant
public API. See platform services.
The smallest complete host
This is the actual interactive entry point from Hello. HelloApp owns the
application-specific view graph; the host owns the terminal, clock, clipboard,
and loop.
// Copyright (c) 2026 C. Klukas. All rights reserved.
// SPDX-License-Identifier: MIT
//
// ckVision Hello — a compact visual integration example; see
// docs/hello-example.md for its behavior contract and golden coverage.
#include "cvision/term/posix_clock.hpp"
#include "cvision/term/terminal_clipboard.hpp"
#include "cvision/term/posix_terminal.hpp"
#include "cvision/ui/application.hpp"
#include "hello_app.hpp"
int main() {
ckv::term::PosixClock clock; ckv::term::PosixTerminal terminal(clock);
ckv::term::TerminalClipboardWriter clipboard(terminal);
ckv::ui::Application app(terminal, clock, clipboard); ckv::hello::HelloApp hello(app);
app.run(); return 0;
}
The next step is the Hello tutorial. It explains every object above, includes all of the app source, and shows the resulting frames.
Choose an example by problem
| You need | Start with |
|---|---|
| A menu, status line, command, and message box | Hello |
| A general application shell with windows and a form | Gallery |
| Resizable layout containers | Layout guide |
| Forms, validation, help, standard dialogs, and a wizard | Dialogs and commands |
| Editing, lists, trees, tables, tabs, and utility chrome | Widget gallery |
| Images or custom raster drawing | Graphics |
Client model in one minute
Application owns a root View. Your app inserts a Desktop beneath that
root. The Desktop owns top/bottom docks, windows, and transient popups. A
window owns one content view, and layout containers or ordinary View objects
own the controls below it. Ownership always flows through std::unique_ptr;
non-owning pointers are only cached for later interaction.
Input enters Application, which gives the focused/modal part of that tree
first chance to handle it, then resolves command key bindings. Painting flows
the other way: the tree paints into a frame, then the terminal presenter emits
the minimal terminal update. The object model gives the
complete picture.