Libghostty-vt 1.0 shipped 6 November 2026 with a stable C ABI under semver. Coding tools, agent UIs, editors, and TUIs can pin against it instead of maintaining yet another escape-sequence parser.
Adoption already outran the app: JetBrains wired IDE terminals through the library for a reported 12.5 million active users before the 1.0 label. You still own windowing and pixels. The library owns grid, cursor, styles, scrollback, and reflow after you feed it bytes.
What Libghostty 1.0 Actually Is
From Mitchell Hashimoto’s 1.0 write-up, libghostty-vt is the portable terminal-emulation core pulled out of Ghostty and exposed as C. PTY output, a recording, a socket stream – same entry point. Parse happens inside; draw stays yours.
Opaque handles. Enum-keyed getters and setters so new fields do not reshuffle symbols. Link newer headers against an older shared library and the call returns GHOSTTY_UNSUPPORTED instead of silent memory trash. That is the whole stability story: break loudly at the API edge, not in production frames.
MIT license. Default runtime wants libc. Flip SIMD off if you need freestanding. Bundled pieces – simdutf, Google Highway, a compact Unicode table, Wuffs for Kitty graphics – stay permissive and show up in a machine-readable manifest. One cited load test held 10,000 live terminals-with-shells on a 4-core / 8 GB Linux box. Small enough that “how many sessions fit” stops being the scary question.
Install Libghostty 1.0 and Run a First Terminal
Start at lib.ghostty.org. As of the 1.0.0 install docs, source builds expect Zig 0.17 on PATH. You are not writing Zig; the build graph is. Wrong minor → hard fail. Zig’s version sits outside the ABI promise, so pin it in CI the same way you pin the tarball.
Release files live here:
https://release.files.ghostty.org/libghostty-vt/1.0.0/
Take the signed source tarball (plus the deps tarball for offline). Verify with minisign and SHA256SUMS from the install page. Turns out the GitHub tag zip is the wrong artifact – more on that in pitfalls.
- Install Zig 0.17.
- Download and unpack
libghostty-vt-1.0.0.tar.gzfrom the release host. - Build and install:
curl -LO https://release.files.ghostty.org/libghostty-vt/1.0.0/libghostty-vt-1.0.0.tar.gz
tar -xzf libghostty-vt-1.0.0.tar.gz
cd libghostty-vt-1.0.0
zig build -Doptimize=ReleaseFast --prefix "$HOME/.local"
You get shared + static libs, headers, pkg-config, and CMake config. Minimal C (shape matches the official first-terminal sample):
#include <stdio.h>
#include <string.h>
#include <ghostty/vt.h>
int main(void) {
GhosttyTerminal terminal;
ghostty_terminal_new(NULL, &terminal, 80, 24);
const char *text = "Hello, x1b[1;32mworldx1b[0m!rn";
ghostty_terminal_vt_write(terminal, (const uint8_t *)text, strlen(text));
GhosttyFormatter formatter;
ghostty_formatter_terminal_new(NULL, &formatter, terminal);
uint8_t *buf = NULL;
size_t len = 0;
ghostty_formatter_format_alloc(formatter, NULL, &buf, &len);
fwrite(buf, 1, len, stdout);
putchar('n');
ghostty_free(NULL, buf, len);
ghostty_formatter_free(formatter);
ghostty_terminal_free(terminal);
return 0;
}
Link:
export PKG_CONFIG_PATH="$HOME/.local/lib/pkgconfig"
cc -o hello hello.c $(pkg-config --cflags --libs libghostty-vt)
-Wl,-rpath,"$HOME/.local/lib"
./hello
Stdout shows plain Hello, world!. Color sat in terminal state; the default plain formatter strips styles. For a full GUI shell on the same API, clone Ghostling – one C file plus Raylib, the blog’s ~1,500-line reference.
Pro tip: Prefer CMake FetchContent or the XCFramework / WASM artifacts when your platform offers them. As of 1.0.0 there are still no prebuilt packages for Linux, FreeBSD, or Windows – source build or wait on distros. Packaging hooks shipped on purpose.
Common Pitfalls on First Embed
Skim-only readers lose hours here.
- Wrong tarball. GitHub’s auto archive for a tag lacks the emit-lib selector. You compile Ghostty the app. Always pull
libghostty-vt-VERSION.tar.gzfromrelease.files.ghostty.org(per the installing docs). - Zig pin. 1.0.0 docs require Zig 0.17. Different libghostty-vt versions may demand different Zig minors. Pin both in CI; “recent Zig” is not a strategy.
- Formatter vs live paint. Official first-terminal guide: formatter = snapshots (save, print, tests). Live UI frames go through
GhosttyRenderState– update, walk dirty rows/cells, clean. Formatter-in-a-frame-loop is the wrong shape. - Raw newlines. Lone
nmoves down and leaves the column alone. PTY line discipline usually expands torn. Files and bare sockets do not. Feedrnyourself or the grid looks “broken.” - Build-mode skew. Community reports: root binary on ReleaseFast while the vendored ghostty-vt dep stayed Debug → page-integrity panics on wide-cell overwrite. Match optimize modes across that edge.
- No distro packages on many hosts yet. Budget source builds until packagers land 1.0.
Check every GhosttyResult. Valid API use is meant to return codes (alloc failure, unsupported ops), not abort your process.
It’s odd how little of terminal work is “draw glyphs” and how much is decades of sequence edge cases. Sharing one fuzzed core is the boring infrastructure move that finally stuck.
Libghostty vs libvterm, VTE, and xterm.js
The catch is you are picking an embed engine, not a desktop app. Tradeoffs diverge from “Ghostty vs Kitty” posts.
| Engine | Best fit | ABI / packaging | Modern protocols | Notes for embedders |
|---|---|---|---|---|
| libghostty-vt 1.0 | New terminals, agents, IDEs, WASM | Stable C ABI, pkg-config/CMake, XCFramework, WASM builds | Strong (Kitty keyboard/graphics path, reflow, rich styles) | You supply PTY + renderer; SIMD parser; MIT |
| libvterm | Existing Neovim-class embeds | Mature C lib, slower historical upstream cadence | More conservative; Neovim kept local patches | Neovim’s approved PR moving to libghostty-vt (#39773) is the signal – closes a long scrollback-reflow pain |
| VTE (libvte) | GTK desktop terminals | GNOME stack | Solid classic VT | GTK lock-in; weak general-embed story |
| xterm.js | Browser / Electron | npm | Good web baseline; Kitty keyboard thinner than native engines | JS parser path; native/WASM cores win when you need parity with desktop VT behavior |
Libghostty’s hard con today: you build it yourself on several OSes, and chrome (tabs, splits, config UI) is 100% your job – by design. The hard pro: one fix from a large consumer lands for everyone else. Language bindings already cover Rust, Go, Python, Swift, JS, Dart, .NET, Elixir, Java, and more; awesome-libghostty tracks well over a hundred projects as of the 1.0 announcement.
Will distros ship 1.0 packages fast enough that “Zig on PATH” stops being the default pain? Open question for the next quarter.
FAQ
Is Libghostty 1.0 free for commercial products?
Yes. MIT. No copyleft in the documented dependency tree.
Do I need Zig at runtime?
No. Zig builds the C library (and the optional native Zig module). Your binary links the .so / .a / dylib / WASM like any other C dep. Runtime = C ABI, optional libc. A Go or Rust service can cgo/FFI against the installed lib and never call zig after CI.
Can I drop this into an existing editor terminal tomorrow?
For VT state, yes at feature level – JetBrains already runs at scale; Neovim’s replacement PR is approved and waiting on packaging. Libghostty-vt is not a PTY manager, font shaper, or window system. Budget input encoding, resize/reflow policy, and a real render path. Parse-and-dump for tests or agents reading TUI output? The hello path above is same-day work.
Next step: pin Zig 0.17, build 1.0.0 from the official tarball, run hello, then open Ghostling and swap Raylib for the UI kit you already ship. Shortest line from release notes to product terminal.