# How to Integrate libghostty-vt into a C Project for Terminal Emulation

> Integrate libghostty-vt into your C project for terminal emulation. Learn how to build, link, and initialize ghostty-vt to parse VT streams efficiently.

- Repository: [Ghostty/ghostty](https://github.com/ghostty-org/ghostty)
- Tags: how-to-guide
- Published: 2026-05-01

---

**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:

```bash
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`](https://github.com/ghostty-org/ghostty/blob/main/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`](https://github.com/ghostty-org/ghostty/blob/main/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`](https://github.com/ghostty-org/ghostty/blob/main/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`](https://github.com/ghostty-org/ghostty/blob/main/include/ghostty/vt/key.h) and [`include/ghostty/vt/mouse.h`](https://github.com/ghostty-org/ghostty/blob/main/include/ghostty/vt/mouse.h) | Convert keyboard and mouse events into VT escape sequences. |
| **Protocol Parsers** | [`include/ghostty/vt/osc.h`](https://github.com/ghostty-org/ghostty/blob/main/include/ghostty/vt/osc.h) and [`include/ghostty/vt/sgr.h`](https://github.com/ghostty-org/ghostty/blob/main/include/ghostty/vt/sgr.h) | Parse Operating System Commands (OSC) and Select Graphic Rendition (SGR) attributes. |
| **Memory Management** | [`include/ghostty/vt/allocator.h`](https://github.com/ghostty-org/ghostty/blob/main/include/ghostty/vt/allocator.h) | Provides hooks for custom allocators to control all library heap operations. |
| **Build Information** | [`include/ghostty/vt/build_info.h`](https://github.com/ghostty-org/ghostty/blob/main/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:

1. **Create a terminal instance** – Call `ghostty_terminal_new()` with desired columns, rows, and scrollback limits. This function is defined at lines 84–86 of [`include/ghostty/vt/terminal.h`](https://github.com/ghostty-org/ghostty/blob/main/include/ghostty/vt/terminal.h).
2. **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.
3. **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.
4. **Extract and format screen contents** – Instantiate a `GhosttyFormatter` with `ghostty_formatter_terminal_new()`, then call `ghostty_formatter_format_alloc()` to render the screen as plain text, VT sequences, or HTML.
5. **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`](https://github.com/ghostty-org/ghostty/blob/main/example/c-vt-formatter/src/main.c):

```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`](https://github.com/ghostty-org/ghostty/blob/main/example/c-vt-effects/src/main.c) shows a bell handler:

```c
#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:

```c
#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`](https://github.com/ghostty-org/ghostty/blob/main/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-vt` to generate `libghostty-vt.a` or `.so` for linking.
- **Initialize state** with `ghostty_terminal_new()` and configure options via `GhosttyTerminalOptions`.
- **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()` and `ghostty_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.