Odin bindings for libghostty-vt — graphical terminal emulator and embeddable quake-style game console (raylib)
Stars
★ 2
Forks
⑂ 0
Language
Odin
Size
73 kB
Last Push
15d ago
Forged
1mo ago
gamedevghosttyodinodin-langraylibterminal
# ghosdin
[](LICENSE)
[](https://odin-lang.org/)
[](https://ziglang.org/)
[](https://www.raylib.com/)
[](#)
Odin bindings for [libghostty-vt](https://github.com/ghostty-org/ghostty) — the
zero-dependency VT terminal parser/state library from the Ghostty project.
Includes a graphical terminal emulator, an embeddable game dev console,
and an idiomatic Odin wrapper.
## What's Here
```
ghosdin/
├── vendor/ghostty_vt/
│ ├── ghostty_vt.odin Raw C FFI bindings (complete API)
│ └── terminal.odin Idiomatic Odin wrapper (Term, iterators, helpers)
├── pty/ Shared POSIX PTY interface (forkpty, non-blocking I/O)
├── render_rl/ Shared raylib helpers (cell render, font, key encoding)
├── console/ Embeddable quake-style dropdown console
├── termview/ Standalone graphical terminal (raylib + PTY)
├── demo/ Headless demo (bindings smoke test)
├── example/ Example game with embedded console
├── docs/architecture.md Architecture and data flow
├── justfile Build commands
└── ghostty/ Ghostty source (cloned, gitignored)
```
## Quick Start
### Prerequisites
- [Odin](https://odin-lang.org/) `dev-2026-05` or newer (the `dev-2026-05` API set is what the bindings target)
- [Zig](https://ziglang.org/) 0.15.2 — to build libghostty-vt
(pinned in `.mise.toml`; upstream ghostty does not yet support 0.16)
- [just](https://github.com/casey/just) — task runner
### Setup
```bash
git clone <repo-url> ghosdin && cd ghosdin
git clone --depth 1 https://github.com/ghostty-org/ghostty.git
just dev
```
### Commands
```
just dev Build + launch the graphical terminal
just run-demo Run the headless demo
just run-example Launch the example game (` to toggle console)
just build Build everything
just check-all Type-check all packages
just debug Build + run in debug mode
just info Show toolchain and build info
just clean Clean all artifacts
just update Pull latest ghostty + rebuild
just test-lib Run libghostty-vt's test suite
```
## Packages
### vendor/ghostty_vt — Bindings
Complete Odin mapping of the libghostty-vt C API, plus an idiomatic wrapper.
#### Raw bindings (`ghostty_vt.odin`)
```odin
import gvt "vendor/ghostty_vt"
term: gvt.Terminal
opts := gvt.Terminal_Options{cols = 80, rows = 24, max_scrollback = 1000}
gvt.terminal_new(nil, &term, opts)
defer gvt.terminal_free(term)
data := "\x1b[1;32mHello!\x1b[0m\r\n"
gvt.terminal_vt_write(term, raw_data(data), len(data))
```
#### Idiomatic wrapper (`terminal.odin`)
```odin
import gvt "vendor/ghostty_vt"
t, err := gvt.term_init(80, 24)
defer gvt.term_destroy(&t)
gvt.term_write(&t, "\x1b[1;32mHello!\x1b[0m\r\n")
title := gvt.term_title(&t)
cx := gvt.term_cursor_x(&t)
// Render iteration
gvt.term_render_update(&t)
row_it := gvt.term_render_rows(&t)
for row in gvt.render_row_next(&row_it) {
cell_it := gvt.term_render_cells(&t)
for cell in gvt.render_cell_next(&cell_it) {
// cell.codepoint, cell.fg_color, cell.style, etc.
}
}
```
#### API Coverage
| Module | Description |
|-----------------|----------------------------------------------------|
| Terminal | Create terminals, feed VT data, query/set state |
| Render State | Incremental dirty-tracking for renderers |
| Screen/Grid Ref | Cell and row access, grapheme clusters, hyperlinks |
| SGR Parser | Parse styling escape sequences |
| OSC Parser | Parse operating system commands |
| Key Encoder | Encode keyboard events to escape sequences |
| Mouse Encoder | Encode mouse events to escape sequences |
| Formatter | Export content as plain text, VT, or HTML |
| Modes | ANSI and DEC terminal mode utilities |
| Focus/Paste | Focus encoding, paste safety + bracketed encoding |
| Selection | Grid-ref selection ranges |
| Kitty Graphics | Image storage, placement iteration, render geometry|
| Sys | Runtime callbacks (PNG decode, log) |
| Allocator | Custom memory allocator support |
| Build Info | Query compile-time library configuration + version |
### console — Embeddable Game Dev Console
Drop-in quake-style terminal for raylib games. Press `` ` `` to toggle.
```odin
import con "ghosdin/console"
// In your game init:
console := con.create() // or con.create(con.Config{...})
defer con.destroy(&console)
// In your game loop:
con.update(&console) // handles toggle key + keyboard when open
con.draw(&console) // renders the overlay (call after your game draws)
// Game input gating:
if !con.is_open(&console) {
// process game input only when console is closed
}
```
Features:
- Spawns a real PTY shell — run any command
- Smooth slide-in/out animation
- Configurable: dimensions, colors, opacity, toggle key, font size
- Captures keyboard when open so game doesn't get stray input
- Full VT escape sequence support (colors, cursor, modes)
### termview — Graphical Terminal
A working terminal emulator in ~300 lines of Odin:
- Spawns a PTY with `$SHELL`
- Feeds output through libghostty-vt
- Renders the grid with raylib (OpenGL)
- Keyboard input (printable chars, special keys, ctrl combos)
- Colors, bold, underline, strikethrough, cursor
```
just run-termview
```
#### Screenshots
- `F12` — save the full window as `termview_<timestamp>.png` in the working directory.
- Click and drag — capture a cell-aligned region as `termview-region_<timestamp>.png`,
and copy the underlying text into the system clipboard at the same time.
### example — Game + Console Demo
A small raylib game (WASD movement, particles) with the console embedded.
Press `` ` `` to drop down a terminal overlay.
```
just run-example
```
## Architecture
```
PTY ──bytes──> ghostty-vt ──render state──> raylib
^ |
└──────────── keyboard input ────────────────┘
```
See [docs/architecture.md](docs/architecture.md) for the full writeup.
## Roadmap
The `vendor/ghostty_vt` bindings will eventually be extracted into their
own standalone repository as a proper Odin package, making them easy to
import without pulling in the full ghosdin project.
## License
Bindings and demo code: MIT
libghostty-vt: See [Ghostty's license](https://github.com/ghostty-org/ghostty/blob/main/LICENSE)