libtermy overview
Build a native terminal with Termy's engine. Start here for Rust and C integration, rendering contracts, and agent-readable documentation.
libtermy is the embeddable terminal engine used by Termy. The Rust crate is
termy_core; its C ABI is declared in termy.h. It provides terminal parsing,
PTY sessions, scrollback, input encoding, events, search, and renderer-neutral
frames. Your application provides the window, renderer, and platform integration.
libtermy is in beta. Pin a Termy commit, build the library and bindings from that same revision, and validate upgrades. Neither Rust source compatibility nor C struct layouts are guaranteed between releases.
Choose an API
| What you are building | Start with | Session owner |
|---|---|---|
| Native Rust application | Rust quick start | libtermy can launch and own the PTY |
| macOS app in Swift or SwiftUI | Swift quick start | libtermy can launch and own the PTY |
| C, C++, Objective-C, or another FFI host | C ABI quick start | libtermy can launch and own the PTY |
| Remote terminal, replay viewer, or externally managed session | Display-only examples in either quick start | Your transport feeds output and receives input/replies |
| Multiplexer client with replica terminals, or a static engine-only library | Engine C library | Your host owns the PTY and transport; libtermy_engine only parses and encodes |
| Browser terminal or Node.js PTY | Web terminal packages | See the package-specific guides |
| Coding agent implementing an integration | Agent integration guide | Choose explicitly before writing code |
What is available in beta
| libtermy owns | Your host owns |
|---|---|
| VT parsing, grid state, scrollback, terminal modes | Windows, tabs, panes, focus, and accessibility |
| Native PTY startup, input writes, and resize | Session lifecycle and application shutdown policy |
| Full frames, dirty spans, cursor and scroll metadata | Retained cell storage, text shaping, GPU resources, and drawing |
| Keyboard and mouse protocol encoding | OS event translation, IME, shortcuts, selection, and paste policy |
| Theme resolution and measured cell dimensions | Font availability, scale conversion, padding, and layout |
| Shell, title, bell, progress, and clipboard requests | Application chrome and clipboard permission decisions |
| Search, OSC 8 links, special-glyph geometry, Kitty image placements | Search navigation, URL opening, geometry painting, and image compositing |
A terminal handle represents one terminal surface. Creating one does not create a visible widget. Owning a PTY and rendering its output are separate jobs.
Rust quick start
Begin with a deterministic display-only Rust example, then switch to a PTY-backed terminal. The Rust guide includes configuration, launch parameters, and an event-draining example.
Rich Rust rendering and the engine boundary
The compact frame API works across Rust and C. Rust also exposes complete cell text, underline styles, live palette revisions, and generation-checked reads. Use the rendering guide to choose a contract. The internal terminal engine is private; do not import backend implementation types into an embedder.
Display-only terminals
Feed process output into feed_output; send user input to the external session
owner. write does nothing without an owned PTY. Protocol replies also need a
route back to the external process. See events and replies.
C ABI quick start
Build the shared library and run a complete C example.
The guide also covers PTY creation, linking, Swift bindings, and status handling.
There is no separate prebuilt native SDK distribution documented here: build
termy_core and vendor the matching header from the same checkout.
Drive the render loop
- Load configuration, measure cells, and create a terminal with a nonzero grid.
- Request and retain one full frame.
- Schedule terminal work when output, input, resize, or host timers require it.
- Drain events and protocol replies; continue while the drain reports more work.
- Take a frame update, patch the retained grid, and update cursor/scroll metadata.
- Paint affected content, then return to idle.
Read rendering and damage before implementing step 5. Full-frame cells are row-major; partial-frame cells are in dirty-span order. They are not interchangeable arrays.
Shared special-glyph plans
Use the shared glyph geometry for supported block, box-drawing, sextant, Braille, rounded-corner, and diagonal characters. The geometry and graphics section explains row context, sparse plans, and pixel snapping.
Kitty clipboard callbacks from C
Clipboard callbacks are synchronous and borrowed data expires when the callback returns. See clipboard integration for permission handling and reply lifetimes.
Batched special-glyph plans from C
Patch the retained full grid first, then build a sparse plan with
termy_cells_build_glyph_render_plan. Plan entries address that full grid.
See rendering.
Input, search, and links
Input and navigation covers mode-aware keyboard and mouse encoding, bracketed paste, viewport coordinates, scrollback search, and link lookup. Encoders return bytes; your host must send them.
Ownership and threading
Serialize calls to each C terminal handle. Only the wake-channel wait and notify functions have a documented concurrency exception. Read the ownership and API reference before building bindings; it lists allocation/free pairs, status codes, and safe shutdown order.
Beta expectations
Keep your dependency revision, header, binary, and generated bindings together.
Do not interpret a familiar function name as a promise of unchanged struct
layout. The Rust 0.2 API removed raw-backend access including Terminal::with_term
and TerminalOptions::term_config; use the public renderer-neutral types.
Validate an integration
The troubleshooting guide provides a smoke-test matrix and checks for blank frames, stale redraws, bad coordinates, missing replies, and teardown crashes.
Agents can read this page as Markdown, the
documentation index, or the full documentation text.
Every guide in this section also has a .md URL.