How to Integrate libghostty-vt into a C Project for Terminal Emulation
To integrate libghostty-vt into a C project, build the library with the -Demit-lib-vt flag, link the resulting libghostty-vt.a or libghostty-vt.so, and initialize a terminal instance with ghostty_terminal_new() to begin parsing VT streams.
libghostty-vt is the standalone C library extracted from the Ghostty terminal emulator (ghostty-org/ghostty) that powers its VT parsing, screen state management, and output formatting. It provides a complete, embeddable virtual terminal implementation designed for integration into PTY-based applications, custom terminal emulators, and shell environments without requiring the full Zig codebase.
Building libghostty-vt from Source
The library is built using Zig's build system. To emit the C library for external linking, enable the -Demit-lib-vt flag:
zig build -Demit-lib-vt
This produces libghostty-vt.a (static) or libghostty-vt.so (shared on Linux) in your build output directory. Link this library in your C project build configuration (e.g., -lghostty-vt with the appropriate -L path), and include the umbrella header include/ghostty/vt.h from the repository.
Core Architecture and Headers
The library is modular, with distinct headers for specific responsibilities:
| Component | Header | Purpose |
|---|---|---|
| Terminal State | include/ghostty/vt/terminal.h |
Holds emulator state including screen buffers, cursor position, scrollback, Kitty graphics, and mode flags. |
| Formatter | include/ghostty/vt/formatter.h |
Transforms the terminal grid into plain text, VT-encoded sequences, or HTML output. |
| Input Encoding | include/ghostty/vt/key.h and include/ghostty/vt/mouse.h |
Convert keyboard and mouse events into VT escape sequences. |
| Protocol Parsers | include/ghostty/vt/osc.h and include/ghostty/vt/sgr.h |
Parse Operating System Commands (OSC) and Select Graphic Rendition (SGR) attributes. |
| Memory Management | include/ghostty/vt/allocator.h |
Provides hooks for custom allocators to control all library heap operations. |
| Build Information | include/ghostty/vt/build_info.h |
Query compile-time features such as SIMD support and Kitty graphics availability. |
Step-by-Step Integration Workflow
Embedding the library follows a consistent five-step pattern:
- Create a terminal instance – Call
ghostty_terminal_new()with desired columns, rows, and scrollback limits. This function is defined at lines 84–86 ofinclude/ghostty/vt/terminal.h. - Feed VT-encoded data – Invoke
ghostty_terminal_vt_write()(lines 85–87) whenever your application receives bytes from a PTY, SSH stream, or file descriptor. - Register effect callbacks – Use
ghostty_terminal_set()(lines 40–44) to configure side effects such as bell notifications (GHOSTTY_TERMINAL_OPT_BELL), title changes, or PTY writes. - Extract and format screen contents – Instantiate a
GhosttyFormatterwithghostty_formatter_terminal_new(), then callghostty_formatter_format_alloc()to render the screen as plain text, VT sequences, or HTML. - Clean up resources – Free the formatter, terminal instance, and any allocated buffers using the corresponding
ghostty_*_free()functions.
Practical Implementation Examples
Creating a Terminal and Processing VT Data
This example demonstrates initialization, feeding raw VT data, and extracting the screen as plain text. Pattern adapted from example/c-vt-formatter/src/main.c:
#include <ghostty/vt.h>
#include <stdio.h>
#include <string.h>
int main(void) {
GhosttyTerminal term;
GhosttyTerminalOptions opts = {
.cols = 80,
.rows = 24,
.max_scrollback = 1000,
};
if (ghostty_terminal_new(NULL, &term, opts) != GHOSTTY_SUCCESS) {
return 1;
}
const char *data = "Hello, world!\r\n";
ghostty_terminal_vt_write(term,
(const uint8_t *)data,
(size_t)strlen(data));
GhosttyFormatter fmt;
GhosttyFormatterTerminalOptions fmt_opts = GHOSTTY_INIT_SIZED(GhosttyFormatterTerminalOptions);
fmt_opts.emit = GHOSTTY_FORMATTER_FORMAT_PLAIN;
fmt_opts.trim = true;
if (ghostty_formatter_terminal_new(NULL, &fmt, term, fmt_opts) != GHOSTTY_SUCCESS) {
return 1;
}
uint8_t *buf = NULL;
size_t len = 0;
if (ghostty_formatter_format_alloc(fmt, NULL, &buf, &len) != GHOSTTY_SUCCESS) {
return 1;
}
fwrite(buf, 1, len, stdout);
ghostty_free(NULL, buf, len);
ghostty_formatter_free(fmt);
ghostty_terminal_free(term);
return 0;
}
Handling Terminal Effects (Bell Callbacks)
Registering callbacks allows your application to respond to terminal events. This snippet from example/c-vt-effects/src/main.c shows a bell handler:
#include <ghostty/vt.h>
#include <stdio.h>
void my_bell_cb(GhosttyTerminal term, void *userdata) {
(void)term;
fprintf(stderr, "🔔 Bell received!\n");
}
int main(void) {
GhosttyTerminal term;
GhosttyTerminalOptions opts = { .cols = 80, .rows = 24, .max_scrollback = 0 };
ghostty_terminal_new(NULL, &term, opts);
ghostty_terminal_set(term,
GHOSTTY_TERMINAL_OPT_BELL,
(const void *)my_bell_cb);
const uint8_t bel = 0x07;
ghostty_terminal_vt_write(term, &bel, 1);
ghostty_terminal_free(term);
return 0;
}
Responding to Size Queries (XTWINOPS)
Applications can provide terminal dimensions to VT queries using the size effect. This example handles the CSI 14 t size request:
#include <ghostty/vt.h>
#include <stdbool.h>
bool size_cb(GhosttyTerminal term, void *userdata,
GhosttySizeReportSize *out) {
(void)term;
(void)userdata;
GhosttySizeReportSize sz = {
.cols = 80,
.rows = 24,
.pixel_width = 800,
.pixel_height = 600,
};
*out = sz;
return true;
}
int main(void) {
GhosttyTerminal term;
GhosttyTerminalOptions opts = { .cols = 80, .rows = 24, .max_scrollback = 0 };
ghostty_terminal_new(NULL, &term, opts);
ghostty_terminal_set(term,
GHOSTTY_TERMINAL_OPT_SIZE,
(const void *)size_cb);
const char query[] = "\033[14t";
ghostty_terminal_vt_write(term,
(const uint8_t *)query,
sizeof(query) - 1);
ghostty_terminal_free(term);
return 0;
}
Memory Management and Custom Allocators
By default, libghostty-vt uses the standard C allocator. For applications requiring custom heap management, pass a GhosttyAllocator structure to ghostty_terminal_new(). The allocator interface is defined in include/ghostty/vt/allocator.h, allowing you to redirect all internal allocations to your own memory pools or tracking systems.
Summary
- Build the library using
zig build -Demit-lib-vtto generatelibghostty-vt.aor.sofor linking. - Initialize state with
ghostty_terminal_new()and configure options viaGhosttyTerminalOptions. - Parse input by feeding bytes to
ghostty_terminal_vt_write()whenever data arrives from the PTY. - Handle side effects by registering callbacks through
ghostty_terminal_set()for bells, title changes, and size queries. - Extract output using the formatter API (
ghostty_formatter_terminal_new()andghostty_formatter_format_alloc()) to render screens as plain text, VT sequences, or HTML.
Frequently Asked Questions
What is libghostty-vt and how does it differ from the full Ghostty application?
libghostty-vt is the core C library that implements the virtual terminal emulation logic from the Ghostty project. While the full Ghostty application is a terminal emulator built in Zig with a GUI frontend, libghostty-vt provides only the platform-agnostic C API for parsing VT sequences and managing terminal state, allowing integration into any C or C++ project without the Zig runtime or GUI dependencies.
How do I build libghostty-vt as a shared library instead of static?
By default, zig build -Demit-lib-vt produces a static archive (libghostty-vt.a). To generate a shared library (.so on Linux, .dylib on macOS, .dll on Windows), specify the shared library output in your Zig build configuration or use platform-specific packaging tools to convert the static archive. The build system supports standard Zig target options for controlling the output artifact type.
Can I use libghostty-vt without installing Zig in my production environment?
No, Zig is required to compile libghostty-vt from source because the library is implemented in Zig and exported via the C ABI. However, once built, the resulting libghostty-vt.a or .so file is a standard C library that links against any C project without requiring the Zig compiler or runtime in the deployment environment.
How do I extract the screen contents as HTML rather than plain text?
When configuring the formatter options, set the emit field of GhosttyFormatterTerminalOptions to GHOSTTY_FORMATTER_FORMAT_HTML instead of GHOSTTY_FORMATTER_FORMAT_PLAIN. The ghostty_formatter_format_alloc() function will then allocate a buffer containing an HTML representation of the terminal screen, including color and style information encoded as CSS or inline styles.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →