Skip to content

Terminal Buffer Model

The Buffer

A terminal maintains a buffer of character cells organized in rows and columns.

┌─────────────────────────┐
│ scrollback row 0        │ ─┐
│ scrollback row 1        │  │ scrollback (history)
│ ...                     │  │
│ scrollback row N        │ ─┘
├─────────────────────────┤ ← base
│ screen row 0            │ ─┐
│ screen row 1            │  │ screen (rows × cols)
│ ...                     │  │
│ screen row (rows-1)     │ ─┘
└─────────────────────────┘

Regions

RegionWhat it isEmpty when
screenThe fixed rows × cols grid. What the terminal renders.Never
scrollbackLines that scrolled off the top of the screen.Alt screen mode
bufferEverything: scrollback + screen.Never
viewportWhat's visible at the current scroll position. At bottom: same as screen. Scrolled up: shows scrollback.Never

Normal Mode vs Alt Mode

Two separate buffers, not regions within one:

  • Normal mode (default): Primary buffer. Output scrolls, scrollback accumulates above the screen. Used by shells, build tools, inline CLI.
  • Alt mode (\x1b[?1049h): Separate clean rows × cols buffer, no scrollback. Used by fullscreen apps (vim, htop, km). Entering saves normal buffer; exiting restores it.
RegionNormal modeAlt mode
screenBottom rows × colsEntire alt buffer
scrollbackLines above screenEmpty
bufferscrollback + screen= screen
viewportWindow at viewportOffset= screen

Cross-Reference: Terminology by Terminal

Core buffer model (well-documented internals)

ConcepttermlessGhosttyKittyxterm.js
Visible areascreenscreen (screen coordinates)screen (@screen)viewport (viewportY)
History abovescrollbackscrollback bufferscrollback / history bufferscrollback
Everythingbufferabsolute buffer (absolute coordinates)text (@text = screen+scrollback)buffer (buffer.active)
Alt screenaltScreen modealternate screen buffersecondary screen (@alternate)alternate (buffer.type)
Scroll positionviewport / viewportOffsetviewportY (0=bottom)scrolled_byviewportY (0=bottom)
Single charactercellGhosttyCellCPUCell / GPUCellIBufferCell
Character rowrowrowline (LineBuf)line (IBufferLine)

Additional terminals (implement VT100/ECMA-48 buffer model)

All modern terminals implement the same underlying buffer model (normal + alternate screen, scrollback region). The table below shows how they expose these concepts:

TerminalVisible areaScrollbackAlt screenNotes
WezTermviewportscrollbackalternateCross-platform, xterm-compatible. Uses "viewport" for visible area.
iTerm2session windowscrollback bufferalternate screenmacOS. "Session" = a terminal instance.
footgrid/windowscrollbackalternateWayland-native, Kitty KB. Minimalist internals.
Alacrittydisplay/gridhistoryalternateGPU-accelerated. grid.rs manages the buffer.
xterm (classic)screensaved lines / scrollbackalternate screenThe original reference terminal. ECMA-48.
Terminal.appwindowscrollbackalternate screenmacOS built-in. 256-color only, limited features.
tmuxpane windowhistoryalternateMultiplexer. Adds its own scrollback on top of terminal's.
VS Code Terminal(xterm.js)(xterm.js)(xterm.js)Embedded xterm.js — same internals.
ContourviewportscrollbackalternateModern terminal with DEC 2026 sync support.
Windows Terminalviewportscrollbackalternate screenUses ConPTY + its own VT parser.

Hightea (km) — UI framework layer

Hightea operates at a higher level (React component tree → rendered cells), not terminal emulation:

Concepthightea termNotes
Visible areaboard.screenThe rendered component tree output
Scroll positionviewport offsetIn ScrollbackView, VirtualView, VirtualList
Single charactercellIn the output buffer
Alt screenfullscreen moderender(<App />, { fullscreen: true })
Coordinate system(x, y) column-firstCSS/DOM convention — different from termless (row, col)

Standards

StandardRelevance
ECMA-48 / ISO 6429CSI/OSC sequences — the foundation. Defines SGR, cursor control, screen modes.
XTerm Control SequencesDe facto terminal standard. Extends ECMA-48 with mouse, paste, true color, alt screen.
smcup/rmcup (terminfo)Enter/exit alternate screen — \x1b[?1049h / \x1b[?1049l.
DEC 2026Synchronized output — batch rendering to prevent tearing.
Kitty Keyboard ProtocolUnambiguous key identification. Supported by Ghostty, Kitty, WezTerm, foot.
OSC 8 HyperlinksClickable hyperlinks in terminal output.

See also vendor/hightea/docs/reference/terminal-matrix.md for the full capability matrix (colors, keyboard protocol, graphics, clipboard) across all terminals.

Coordinate Systems

  • termless: (row, col) — row-first, 0-based. Matches terminal tradition (ANSI sequences are row-first: \x1b[row;colH).
  • Ghostty: 4 coordinate systems (viewport, screen, scrollback, absolute), all row-first.
  • xterm.js: (y, x) — row-first internally (IBufferLine).
  • Hightea: (x, y) — column-first, matching CSS/DOM convention (left, top).

Hightea keeps (x, y) because it's a React-like UI framework where CSS conventions are natural. termless keeps (row, col) because it's a terminal emulator library. Don't unify — each is correct for its domain.

Cell

A cell holds one character with attributes:

  • text, fg (RGB), bg (RGB)
  • bold, faint, italic, underline, strikethrough, inverse, wide

Released under the MIT License.