vt

A terminal emulator in Go. Feed it what a program prints, and read the screen, the scrollback and the modes.

tuios.dev/vt is a terminal emulator in Go. It reads the bytes a program writes to a terminal and keeps the screen they draw: the cells, their colours and attributes, the cursor, the scrollback and the modes. tuios runs every pane on it.

go get tuios.dev/vt

It needs Go 1.26 or later. The default build is pure Go and needs no cgo. The API reference is on pkg.go.dev.

Use it to

  • Run a program in a test and check what it drew.
  • Show a terminal inside a Bubble Tea program or another TUI.
  • Keep a pane's screen in a server and send it to a client that attaches later.

What it covers

  • VT100 to xterm sequences, with a conformance corpus in its tests.
  • Scrollback with reflow on resize.
  • The alternate screen, scroll regions, left and right margins, tab stops, character sets and selective erase.
  • Mouse modes and key encoding, with the kitty keyboard protocol and modifyOtherKeys.
  • Kitty graphics and sixel, OSC 8 links, OSC 133 shell marks, OSC 52 clipboard, desktop notifications and OSC 9;4 progress.
  • OSC 7501, the Program Status Protocol.

Example

package main

import (
	"fmt"

	"tuios.dev/vt"
)

func main() {
	term := vt.New(40, 5)
	defer term.Close()

	// What a program prints goes in.
	term.Write([]byte("hello \x1b[1mworld\x1b[0m\r\n$ "))

	// The screen comes out, as text or cell by cell.
	fmt.Println(term.String())
	fmt.Println(term.CellAt(6, 0).Content) // "w", drawn bold
	fmt.Println(term.CursorPosition())     // column 2, row 1
}

Some sequences ask the terminal a question, such as the cursor position. Read returns the replies, and the host writes them back to the program. With a pseudo-terminal, copy them in a goroutine:

go io.Copy(ptmx, term)

The API

  • Screen is the small interface most users need: Write, Read, Resize, Width, Height, CellAt, CursorPosition, Render, String and Close.
  • Terminal is the full interface that tuios uses. It adds the scrollback, the modes, key and mouse encoding, graphics, and the state a snapshot carries.
  • New and NewWithScrollback return the backend the build selected. NewEmulator returns the pure Go *Emulator.
  • Callbacks reports what a program asks of the host: a new title, a bell, a working directory, a clipboard write, a notification, and private OSC sequences.

Two sub-packages come with it:

  • tuios.dev/vt/snapshot captures an emulator's state, packs it for a wire or a file, and brings another emulator to the same state. Replay turns a state into the bytes that repaint it on any xterm-compatible terminal.
  • tuios.dev/vt/vtgen generates terminal input from a grammar, for fuzzing an emulator. A failure reduces to a script of named sequences a person can read.

The ghostty backend

With the ghostty build tag, New returns an emulator backed by libghostty-vt through cgo. The build needs the library. See docs/ghostty-vt.md for how tuios builds it.

Versions

The module is at v0. The API can change between minor versions. Its tags have the folder name as a prefix, such as vt/v0.1.0. The source is in the vt folder of the tuios repository, under the MIT licence. It started as a copy of the vt package of charmbracelet/x.

On this page