Skip to content

Instantly share code, notes, and snippets.

@MangaD
Created August 3, 2026 12:12
Show Gist options
  • Select an option

  • Save MangaD/cd8b8ab9b4f119ac5214fa4f3424ccd7 to your computer and use it in GitHub Desktop.

Select an option

Save MangaD/cd8b8ab9b4f119ac5214fa4f3424ccd7 to your computer and use it in GitHub Desktop.
The Complete Guide to Terminal User Interfaces (TUIs)

The Complete Guide to Terminal User Interfaces (TUIs)

CC0

Disclaimer: ChatGPT generated document.

A TUI (Terminal User Interface) is an interactive user interface rendered inside a terminal. It occupies the middle ground between a traditional command-line interface (CLI) and a graphical user interface (GUI): keyboard-centric, script-friendly and remote-friendly like a CLI, but with windows/panels, menus, tables, forms, dialogs, mouse support, colors, scrolling, and sometimes even graphics.

Modern TUIs have undergone something of a renaissance. Rust, Go, Python, C++, JavaScript, .NET, and other ecosystems now have sophisticated frameworks, while modern terminals support Unicode, 24-bit color, hyperlinks, mouse events, advanced keyboard protocols, and—in some terminals—actual images.

Image

Image

Image

Image

1. TUI vs CLI vs GUI

The distinction is useful:

CLI TUI GUI
Example git status lazygit GitHub Desktop
Interaction commands keys/mouse/widgets mouse/touch/widgets
Display sequential text screen-oriented graphical windows
Rendering stdout terminal cells pixels
Remote SSH excellent excellent difficult
Automation excellent moderate usually poor
Resource usage tiny low higher
Discoverability low–medium medium–high high

A CLI usually behaves like:

$ git status
$ git add foo.rs
$ git commit

A TUI might instead display:

┌─ Files ──────────────┐┌─ Diff ───────────────────────┐
│ M src/main.rs        ││ - old line                  │
│ A README.md          ││ + new line                  │
│                      ││                             │
├─ Branches ───────────┤├─ Commits ──────────────────┤
│ * main               ││ 31ac922 Fix parser         │
│   feature-x          ││ d02a811 Initial version    │
└──────────────────────┘└─────────────────────────────┘

 [Space] stage    [c] commit    [q] quit

But importantly, those boxes aren't graphical windows. They're usually Unicode characters painted into terminal cells.


2. How a TUI actually works

At the lowest level, a terminal is essentially a grid:

column →
0 1 2 3 4 5 6 ...
┌───────────────
0│H e l l o
1│
2│
↓
row

Each cell may contain:

  • a character
  • foreground color
  • background color
  • attributes such as bold/italic/underline
  • sometimes a wide Unicode glyph occupying two cells

Applications send control sequences mixed with text.

For example:

ESC [ 31 m

means roughly:

switch foreground to red.

And:

ESC [ 10 ; 20 H

means roughly:

move cursor to row 10, column 20.

These belong to the large family of ANSI/ECMA-48/DEC-style terminal control sequences.

A TUI renderer therefore does something conceptually like:

read input
    ↓
update application state
    ↓
calculate layout
    ↓
render widgets into virtual screen buffer
    ↓
compare buffer with previous frame
    ↓
send changed cells/control sequences
    ↓
terminal emulator displays them

That last optimization is important. Good frameworks don't necessarily repaint thousands of cells every frame.


3. The historical lineage

TUIs are much older than the term itself.

Early computing involved physical terminals connected to mainframes and minicomputers.

There were printing terminals/teletypes:

computer → serial line → paper

followed by CRT "glass terminals."

A historically important family was DEC's VT series, particularly the VT100, introduced in 1978.

The VT100 helped popularize cursor positioning and standardized control sequences that heavily influenced today's terminal ecosystem.

Conceptually:

Teletype
   ↓
CRT terminals
   ↓
VT52 / VT100 / VT220 / ...
   ↓
ANSI/DEC control sequences
   ↓
Unix terminal abstraction
   ↓
xterm
   ↓
modern terminal emulators

Modern applications still speak protocols descended from machines that physically existed decades ago.


4. curses: the foundation of Unix TUIs

Writing escape sequences manually quickly became impractical because terminals differed.

Unix therefore developed abstraction systems such as:

termcap
   ↓
terminfo

Applications could ask:

How does this particular terminal move the cursor?

rather than hardcoding one terminal's escape sequence.

The famous curses library appeared in the late 1970s/early 1980s Unix ecosystem.

Today the major implementation is ncurses.

ncurses

ncurses provides abstractions for:

  • cursor movement
  • screen updates
  • windows
  • pads
  • colors
  • keyboard input
  • mouse input
  • terminal capabilities

It remains enormously important. The current ncurses project continues to maintain the curses/terminfo ecosystem. (invisible-island.net)

Classic TUI programs built around curses-style APIs include things such as editors, file managers, installers, configuration tools and system monitors.


5. Terminal emulator vs shell vs TUI

These concepts are frequently confused.

Suppose you open a terminal and run:

nvim

The stack might actually be:

┌──────────────────────────────┐
│ OS / desktop                 │
│                              │
│ ┌──────────────────────────┐ │
│ │ Terminal emulator        │ │
│ │                          │ │
│ │ ┌──────────────────────┐ │ │
│ │ │ Shell: zsh           │ │ │
│ │ │                      │ │ │
│ │ │ $ nvim               │ │ │
│ │ │      ↓               │ │ │
│ │ │ Neovim TUI           │ │ │
│ │ └──────────────────────┘ │ │
│ └──────────────────────────┘ │
└──────────────────────────────┘

The terminal emulator is the graphical application displaying terminal cells.

The shell (bash, zsh, PowerShell, fish...) interprets commands.

The TUI application temporarily takes control of the terminal.

These are separate layers.


6. Modern terminal emulators

Common terminals include:

Linux / Unix

  • xterm
  • GNOME Terminal
  • Konsole
  • foot
  • kitty
  • Alacritty
  • WezTerm
  • Ghostty

macOS

  • Terminal.app
  • iTerm2
  • kitty
  • Alacritty
  • WezTerm
  • Ghostty

Windows

  • Windows Terminal
  • legacy Console Host
  • ConPTY-backed terminals
  • WezTerm
  • Alacritty
  • kitty

Windows Terminal documentation describes Windows Terminal as supporting Command Prompt, PowerShell, WSL and SSH profiles, along with tabs, panes, Unicode/UTF-8 and GPU-accelerated rendering. (Microsoft Learn)

WezTerm is particularly interesting because it's both a terminal emulator and multiplexer. It runs on Linux, macOS, Windows, FreeBSD and NetBSD and supports true color, hyperlinks, advanced text attributes, mouse reporting and several graphics protocols. (WezTerm)

And XTerm remains historically significant: its project describes it as the standard X Window System terminal emulator, with development going back to the 1980s. (XTerm)


7. What does "terminal compatible" actually mean?

This gets surprisingly complicated.

A program commonly sees:

echo $TERM

with values such as:

xterm
xterm-256color
screen
screen-256color
tmux-256color
linux
vt100

Libraries may consult the terminfo database to determine what that terminal claims to support.

But modern applications may additionally examine:

TERM
COLORTERM
TERM_PROGRAM
WT_SESSION
TMUX
SSH_TTY
...

or actively query terminal capabilities.

There is no single perfectly uniform "modern terminal standard."

Compatibility is instead a mixture of:

ECMA-48 / ANSI conventions
        +
DEC VT behavior
        +
xterm extensions
        +
terminfo
        +
terminal-specific extensions

8. Colors

Historically you had something like:

8 colors

black
red
green
yellow
blue
magenta
cyan
white

Then:

16 colors

Basic + bright variants.

Then:

256 colors

Often referred to through:

TERM=xterm-256color

And modern terminals frequently provide:

True color

24-bit RGB
≈ 16.7 million colors

For example:

ESC[38;2;255;100;40m

specifies an RGB foreground.

Current compatibility references show 24-bit color across many modern terminals including Ghostty, kitty, WezTerm, iTerm2 and Alacritty, although advanced features vary considerably beyond color. (Silvery)


9. Unicode transformed TUI design

Classic TUIs looked like:

+------------------+
| CPU: 52%         |
+------------------+

Unicode allows:

╭──────────────────╮
│ CPU  █████░░ 72% │
├──────────────────┤
│ RAM  ███░░░░ 43% │
╰──────────────────╯

Useful characters include:

Box drawing

─ │ ┌ ┐ └ ┘
├ ┤ ┬ ┴ ┼
╭ ╮ ╰ ╯

Blocks

█ ▇ ▆ ▅ ▄ ▃ ▂ ▁

Braille

⠁ ⠃ ⠇ ⠧ ⠷ ⠿

Braille is especially useful for high-resolution terminal charts because one character can represent multiple logical pixels.

Then there are symbols and emoji:

✓ ✗ ⚠ ● ◆ ▶
🐍 🦀 🚀

But Unicode creates hard problems: character width isn't universally trivial.

CJK characters may occupy two cells, combining marks may occupy zero additional cells, emoji sequences can involve multiple Unicode code points, and terminals don't always agree on rendering width.

This is one of the nastier engineering details of serious TUI frameworks.


10. Input

A TUI typically puts the terminal into something resembling raw mode.

Normally terminal input is line-oriented:

hello<Enter>

Raw mode lets the program receive keys immediately:

h
e
l
l
o

Special keys often arrive as escape sequences.

For example, an arrow key might effectively arrive as bytes resembling:

ESC [ A

Frameworks decode these into events such as:

Key::Up
Key::Enter
Ctrl('c')
MouseDown(...)
Resize(...)
Paste(...)

Modern terminal protocols are improving keyboard disambiguation, including the Kitty keyboard protocol, but support isn't universal. Recent compatibility matrices show significant differences between terminals here. (Silvery)


11. Mouse support

Yes, TUIs can use mice.

Terminals can report:

click
release
drag
scroll wheel
coordinates
modifier keys

This enables:

  • clickable buttons
  • scroll bars
  • selectable tables
  • tabs
  • text selection
  • drag operations

Many modern TUI frameworks support mouse input, although keyboard-first interaction remains preferable because terminal applications are frequently used remotely.


12. Images inside terminals

This is one of the strangest modern developments.

Some terminals implement actual graphics protocols.

Major approaches include:

Sixel

An older bitmap protocol experiencing renewed use.

Kitty graphics protocol

Implemented by kitty and increasingly supported elsewhere.

iTerm2 inline images

An escape-sequence-based protocol originating in iTerm2.

Modern terminals such as WezTerm support combinations of iTerm2 images, Kitty graphics and Sixel. (WezTerm)

Consequently a "text interface" can now contain:

text
Unicode
24-bit color
images
animations
charts
hyperlinks

At that point the boundary between TUI and GUI gets surprisingly fuzzy.


13. Popular TUI frameworks by language

This is the modern landscape.

Rust — Ratatui

Ratatui

Probably the best-known modern Rust TUI ecosystem.

Ratatui describes itself as a library for building "fast, lightweight, and rich terminal user interfaces." (Ratatui)

Typical architecture:

App state
   ↓
event loop
   ↓
Frame
   ↓
layout
   ↓
widgets
   ↓
terminal backend

Widgets include things like:

Block
Paragraph
List
Table
Tabs
Gauge
Chart
Scrollbar
Canvas

Rust is an especially good TUI language because it gives you:

  • fast startup
  • low memory usage
  • native executables
  • strong Unicode libraries
  • concurrency
  • excellent CLI ecosystem
  • straightforward binary distribution

14. Go — Bubble Tea

Bubble Tea

Bubble Tea is one of the most influential Go TUI frameworks.

Its architecture is based on The Elm Architecture:

Model
  ↓
Update(message)
  ↓
new Model
  ↓
View()

Conceptually:

func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd)
func (m model) View() string

This architecture works remarkably well for terminals because input naturally arrives as a stream of events/messages.

The Charm ecosystem around Bubble Tea also popularized libraries/tools such as Lip Gloss and Bubbles.

Go is attractive because:

single executable
fast startup
simple concurrency
easy cross-compilation
good networking ecosystem

15. Python — Textual

Textual

Textual takes a substantially higher-level approach.

Think:

terminal + CSS-like styling + widgets + reactive application framework

You can build applications with:

  • buttons
  • trees
  • tables
  • inputs
  • dialogs
  • tabs
  • scrolling containers
  • reactive properties
  • CSS-style layouts
  • event/message systems

It feels more like building a web/desktop application than directly manipulating terminal cells.

Textual can therefore be excellent for:

internal tools
database clients
dashboards
admin consoles
developer tools

Python also has lower-level and simpler choices such as:

  • curses
  • urwid
  • prompt_toolkit
  • Rich
  • blessed

Rich isn't primarily a full-screen application framework, but it is extremely useful for styled terminal output, tables, progress displays and dashboards.


16. C / C++

The historical foundation is:

curses / ncurses

For modern C++, one prominent option is:

FTXUI

FTXUI describes itself as a functional terminal user interface library and provides components, DOM-style composition and screen rendering. (GitHub)

Other interesting low-level systems include:

notcurses
PDCurses
termbox-style libraries

Notcurses is particularly ambitious about modern terminal capabilities such as Unicode, true color and multimedia.


17. .NET / C#

A major framework is:

Terminal.Gui

It provides a cross-platform terminal UI toolkit for .NET.

The programming model feels more like traditional desktop UI programming:

Window
Button
Label
TextField
ListView
Dialog
MenuBar

rather than manually drawing terminal cells.

Another widely used C# terminal ecosystem component is Spectre.Console, particularly good for polished CLI output and interactive prompts.


18. JavaScript / TypeScript

A particularly interesting approach is Ink.

Ink applies React concepts to terminals:

<Box>
  <Text>Hello</Text>
</Box>

So:

React component model
        ↓
terminal renderer

This can be attractive when a team already understands React and Node.js.

Other JS terminal UI projects have included:

blessed
neo-blessed
terminal-kit

19. Java / JVM

Libraries include:

Lanterna
JLine

Lanterna offers higher-level terminal GUI abstractions, while JLine is especially important for sophisticated interactive command-line applications, REPLs and shells.


20. Shell scripting

Even Bash can produce TUIs.

Common tools include:

dialog
whiptail
fzf
gum

For example, dialog can provide:

┌──────────────────────────┐
│ Choose environment       │
│                          │
│  ( ) Development         │
│  (●) Staging             │
│  ( ) Production          │
│                          │
│       < OK >             │
└──────────────────────────┘

without writing a full UI framework.


21. Other ecosystems

There are TUI libraries for almost everything:

Language Libraries / frameworks
Rust Ratatui, Cursive
Go Bubble Tea, tview, termui
Python Textual, Rich, urwid, prompt_toolkit, curses
C ncurses, notcurses
C++ FTXUI, ncurses
C#/.NET Terminal.Gui, Spectre.Console
JS/TS Ink, blessed, terminal-kit
Java Lanterna, JLine
Ruby TTY toolkit
Haskell Brick
Zig various emerging libraries
Shell dialog, whiptail, gum, fzf

Community discussion in 2026 particularly tends to cluster around Ratatui for Rust, Bubble Tea for Go, and Textual for Python, although the "best" choice depends strongly on language and application architecture. (Reddit)


22. Popular TUI applications

There are far more than most people realize.

Editors

Vim
Neovim
Emacs (terminal mode)
Helix
Kakoune

System monitoring

top
htop
btop
glances

Git

lazygit
gitui
tig

Kubernetes

k9s

File management

Midnight Commander
ranger
nnn
lf
yazi

Multiplexers

tmux
GNU screen
Zellij

Database tools

pgcli
mycli
lazysql

Networking

nmtui
bandwhich
gping

Containers

lazydocker

Fuzzy navigation

fzf

GitHub

gh

although gh is primarily CLI-oriented rather than a traditional full-screen TUI.

Modern community discussions still routinely identify htop, tmux, and fzf as staples of the terminal ecosystem. (Reddit)


23. Multiplexers complicate everything

Suppose you run:

Ratatui app
     ↓
tmux
     ↓
SSH
     ↓
remote PTY
     ↓
local terminal

Now capability negotiation becomes tricky.

The application may see:

TERM=tmux-256color

rather than:

TERM=xterm-kitty

Some advanced escape sequences have to pass through tmux.

Thus:

terminal supports feature

does not necessarily imply

application can use feature

A current compatibility guide explicitly notes that multiplexers such as tmux, screen and Zellij can reduce the effective capabilities exposed by the underlying terminal. (FrankenTUI)


24. SSH is one of the TUI's superpowers

Consider a graphical administration application.

Remote usage might require:

VPN
remote desktop
browser
GUI forwarding

A TUI often needs only:

ssh server
k9s

Rendering happens locally in your terminal while the application executes remotely.

This makes TUIs exceptionally useful for:

  • servers
  • cloud infrastructure
  • Kubernetes
  • databases
  • embedded Linux
  • development environments
  • remote machines

And explains why they never disappeared.


25. Cross-platform support

Modern TUI frameworks usually target some combination of:

Linux
macOS
Windows
BSD

Unix-like systems traditionally use pseudo-terminals:

PTY

Windows historically had a substantially different console API.

Modern Windows introduced ConPTY, greatly improving compatibility with Unix-style terminal applications and escape sequences.

This helped make applications such as:

Neovim
fzf
lazygit
Ratatui applications
Bubble Tea applications

much easier to support consistently across Windows and Unix-like systems.

But "cross-platform" still requires testing.


26. The terminal rendering model

Most modern frameworks use immediate-mode rendering.

Instead of saying:

create window
modify label
move button

you often say:

render the entire desired UI from current state

Conceptually:

fn draw(frame: &mut Frame, app: &App) {
    draw_sidebar(frame, app);
    draw_editor(frame, app);
    draw_statusbar(frame, app);
}

The framework maintains buffers:

previous frame
     ↓
diff
     ↑
current frame

and emits only necessary terminal changes.

That is one reason terminal UIs can update smoothly despite their seemingly primitive output protocol.


27. Common TUI architecture

A robust application frequently looks like:

                    ┌──────────────┐
keyboard ──────────►│              │
mouse ─────────────►│ Event loop   │
resize ────────────►│              │
network ───────────►│              │
                    └──────┬───────┘
                           ↓
                    ┌──────────────┐
                    │ App state    │
                    └──────┬───────┘
                           ↓
                    ┌──────────────┐
                    │ UI renderer  │
                    └──────┬───────┘
                           ↓
                    ┌──────────────┐
                    │ Cell buffer  │
                    └──────┬───────┘
                           ↓
                    terminal

This naturally resembles:

  • Elm
  • Redux
  • Model-View-Update
  • unidirectional state architectures

which explains why Bubble Tea's Elm-inspired design and Ratatui's state/render separation work so well.


28. Widgets

Modern frameworks often supply:

Paragraph
Label
Button
Input
TextArea
List
Tree
Table
Tabs
Menu
Popup
Dialog
ProgressBar
Gauge
Sparkline
Chart
Scrollbar
Canvas

But unlike GUI widgets, they're eventually reduced to terminal cells.

A progress bar:

████████████░░░░░░░░ 60%

A sparkline:

▁▂▃▅▄▇█▆▄▃

A tree:

src/
├── app.rs
├── main.rs
└── ui/
    ├── editor.rs
    └── sidebar.rs

This is essentially ASCII/Unicode graphics.


29. Layout

Modern frameworks often support constraints resembling GUI layout engines:

vertical
├── header: 3 rows
├── content: remaining
└── footer: 1 row

Then:

content
├── sidebar: 25%
└── editor: 75%

Some frameworks offer:

  • flex layouts
  • percentages
  • minimum/maximum dimensions
  • fixed dimensions
  • nested containers

Textual goes particularly far toward web-style layout concepts.


30. Responsive design exists in TUIs too

A terminal might be:

80×24

or:

240×70

or a tiny SSH pane:

40×12

Good TUIs therefore adapt.

Large:

┌─ Files ──────┐┌─ Preview ──────────────────┐
│ ...          ││ ...                        │
└──────────────┘└────────────────────────────┘

Small:

┌─ Files ──────────────┐
│ ...                  │
└──────────────────────┘

Exactly the same concept as responsive web design, except measured in character cells.


31. Terminal capabilities worth knowing

Modern TUI developers eventually encounter acronyms like:

CSI
OSC
SGR
DCS
DECSET
DECRST

Some important capabilities include:

SGR

Text styling:

bold
italic
underline
foreground
background

Alternate screen

Lets full-screen applications take over the terminal and restore the previous shell display afterward.

Bracketed paste

Lets the program distinguish typed input from pasted text.

Mouse tracking

Reports mouse activity.

Focus reporting

Tells applications whether the terminal gained/lost focus.

OSC 8

Clickable hyperlinks.

OSC 52

Clipboard interaction.

Synchronized output

Allows terminals to avoid showing partially rendered frames.

Kitty keyboard protocol

Improves keyboard event representation.

Kitty/Sixel/iTerm graphics

Image rendering.

Current support differs considerably by terminal: basic colors are nearly universal, whereas synchronized output, Kitty keyboard, graphics, hyperlinks and clipboard-related capabilities are much less uniform. (Silvery)


32. Why TUIs can flicker

A naïve program might repeatedly:

clear screen
draw everything
clear screen
draw everything

which causes flickering.

Modern renderers instead:

Frame A
   ↓
Frame B
   ↓
calculate changed cells
   ↓
update only differences

and may use synchronized output when supported.

This produces much smoother interfaces.


33. Performance

Terminal rendering has unusual bottlenecks.

Usually the expensive part isn't:

calculating the UI

but:

generating escape sequences
        +
writing them through PTY
        +
terminal parsing
        +
glyph rendering

Especially over:

SSH
serial connections
slow multiplexers

So good libraries minimize output.

A terminal app doing:

60 FPS × 200 × 60 cells

can generate a surprising amount of data if implemented badly.


34. Accessibility

TUIs have both strengths and weaknesses.

Strengths include:

  • entirely keyboard operable
  • usable without precise pointing
  • excellent zoom via terminal font scaling
  • potentially screen-reader compatible
  • high-contrast themes

Problems include:

  • heavy Unicode/icon use
  • color-only information
  • unconventional keyboard navigation
  • custom widgets
  • screen readers struggling with constantly redrawn screens

Accessible TUI design should avoid making color or exotic glyphs the only representation of meaning.


35. Advantages of TUI applications

TUIs are especially attractive when you want:

Low resource consumption

A sophisticated interface may consume a fraction of a browser/Electron application's resources.

Remote execution

SSH is native territory.

Fast startup

Native Rust/Go/C/C++ applications can feel essentially instantaneous.

Keyboard efficiency

Expert users can operate them extremely quickly.

Cross-platform distribution

Especially with Rust and Go binaries.

Automation coexistence

A project can expose both:

mytool deploy --prod

and:

mytool

for an interactive interface.

Developer audience

Developers already live in terminals.


36. Disadvantages

Terminals impose genuine constraints.

Layout precision

You get cells, not arbitrary pixels.

Typography

No normal GUI control over fonts.

Unicode inconsistencies

Glyph width and emoji rendering can differ.

Keyboard ambiguity

Historical terminal protocols weren't designed for today's keyboards.

Feature fragmentation

One terminal supports Kitty graphics; another Sixel; another neither.

Clipboard complexity

Terminal ↔ remote application ↔ SSH ↔ multiplexer ↔ OS clipboard is complicated.

Accessibility

Full-screen dynamically redrawn interfaces aren't automatically accessible.

Discoverability

Keyboard shortcuts must be learned.

Mobile

Terminal applications can technically work on phones but usually aren't optimized for touch.


37. When should you build a TUI?

TUIs are excellent for:

developer tools
DevOps tools
Kubernetes clients
Git clients
database browsers
server administration
log viewers
system monitoring
file managers
SSH tools
build systems
interactive installers
debugging tools
networking tools
AI coding tools

They're less suitable for:

photo editing
video editing
CAD
consumer mobile applications
highly visual design
complex drag-and-drop workflows
maps
graphics-heavy applications

38. Which language/framework should you choose?

A useful practical map is:

Situation Strong candidate
Want maximum native performance Rust + Ratatui
Building cloud/DevOps tooling Go + Bubble Tea
Fast development/internal tool Python + Textual
Existing Python CLI Rich / Textual / prompt_toolkit
C++ project FTXUI
Existing .NET application Terminal.Gui / Spectre.Console
React/Node team Ink
Low-level Unix application ncurses/notcurses
Simple shell workflow gum/dialog/fzf

The three especially influential modern choices are:

Ratatui for Rust Bubble Tea for Go Textual for Python

Their philosophies are noticeably different:

Ratatui
state → frame → widgets → cells

Bubble Tea
model → message → update → view

Textual
application → widgets → events → CSS/layout

39. The TUI ecosystem in one diagram

You can think of the whole stack as:

┌───────────────────────────────────────────────┐
│                   TUI APP                     │
│      lazygit / k9s / htop / your app         │
├───────────────────────────────────────────────┤
│               TUI FRAMEWORK                   │
│ Ratatui / Bubble Tea / Textual / FTXUI / ... │
├───────────────────────────────────────────────┤
│          TERMINAL ABSTRACTION LAYER           │
│ curses / crossterm / terminfo / raw mode     │
├───────────────────────────────────────────────┤
│             TERMINAL PROTOCOLS                │
│ ANSI / ECMA-48 / DEC / xterm / OSC / CSI     │
├───────────────────────────────────────────────┤
│             PTY / ConPTY / SSH                │
├───────────────────────────────────────────────┤
│             TERMINAL EMULATOR                 │
│ kitty / WezTerm / xterm / iTerm2 / WT / ...  │
├───────────────────────────────────────────────┤
│                GUI / OS                       │
│       Linux / macOS / Windows / BSD           │
└───────────────────────────────────────────────┘

Sometimes additional layers appear:

TUI
 ↓
tmux
 ↓
SSH
 ↓
PTY
 ↓
terminal

which is why terminal compatibility is much more complicated than "does ANSI work?"


40. Why TUIs are having another golden age

The terminal used to be constrained by:

monochrome
ASCII
slow serial links
limited keyboards
physical CRT hardware

Today's terminal can provide:

Unicode
24-bit RGB
emoji
mouse
clipboard
hyperlinks
images
GPU rendering
fast local PTYs
SSH
modern keyboard protocols

Meanwhile languages like Rust and Go make it easy to distribute fast, self-contained developer tools.

That's a powerful combination.

The terminal has therefore evolved from:

dumb text display

into something closer to:

portable interactive rendering protocol

while retaining decades of backwards compatibility.

That backward compatibility is simultaneously the terminal's superpower and biggest engineering headache.

A program designed around relatively conservative VT/xterm behavior can work through SSH on an enormous variety of machines. But exploiting modern features—graphics, richer keyboard handling, clipboard access, synchronized rendering—requires capability detection and fallbacks because support still differs significantly among terminals. (Silvery)

And that's perhaps the most interesting thing about TUIs: a modern Ratatui/Textual/Bubble Tea application running in a GPU-accelerated terminal is ultimately descended from software protocols created for physical CRT terminals connected by serial cables in the 1970s. Yet the model remains useful enough that developers are still building new frameworks, terminal emulators and applications around it nearly half a century later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment