What Makes a Terminal 'TUI-Capable': ncurses, terminfo, and Raw Mode
Full-screen terminal applications like htop and vim don't just print text — they take over the entire screen, redraw parts of it selectively, and read your keystrokes one at a time. Here's the layer that makes that possible.
Full-screen terminal applications like htop, vim, and lazygit behave nothing like a normal command printing output line by line — they take over the entire screen, redraw specific regions selectively, and respond to individual keystrokes immediately. A specific library layer is what makes this possible portably.
Why raw text output isn’t enough for a TUI
A normal command’s output is a stream of text the terminal displays line by line, scrolling as needed — a TUI (text user interface) application instead needs to move the cursor to arbitrary positions, redraw only specific changed regions, and read keystrokes as they happen rather than waiting for a full line ended by Enter.
The library that makes this portable: ncurses
ncurses (new curses, a free reimplementation of the older, AT&T-derived curses library) provides an API for exactly this: positioning the cursor anywhere on screen, drawing and clearing specific regions, handling color, and reading individual keystrokes — all without the application needing to know which specific terminal emulator it’s actually running inside.
How ncurses achieves that portability: terminfo
Different terminal emulators historically understood different, incompatible escape sequences for the same operation (like “move cursor to row 5, column 10”) — the terminfo database describes exactly which escape sequences a given terminal type (identified via the $TERM environment variable) actually supports, and ncurses consults it rather than hardcoding one specific terminal’s sequences.
Raw mode: the other essential piece
By default, a terminal operates in cooked mode (also called canonical mode) — input is buffered and only delivered to a program once a full line is submitted (with backspace and line-editing handled by the terminal driver itself). TUI applications instead put the terminal into raw mode, in which every individual keystroke is delivered to the program immediately, unbuffered, with no automatic line editing — necessary for an application to respond instantly to arrow keys or a q keypress rather than waiting for Enter.
Why a terminal sometimes looks broken after a TUI app crashes
If a TUI application crashes or is killed abruptly without properly restoring the terminal to cooked mode and its normal display state, the terminal can be left in raw mode with corrupted display settings — typed characters may not echo normally, or the screen may look wrong. This is exactly the scenario reset or stty sane exists to fix, restoring the terminal’s settings to sane defaults regardless of what state a crashed program left it in.
Why not every terminal environment supports every TUI application well
A genuinely minimal or non-standard terminal environment (a very constrained embedded serial console, certain non-interactive CI log capture contexts) may have a limited or inaccurate terminfo entry, or no real interactive raw-mode support at all — this is why some TUI applications degrade to a simpler text-only fallback mode, or refuse to run, in specific unusual environments.
Why understanding this layer explains TUI application behavior generally
Recognizing that TUI applications rely on ncurses (or an equivalent library), terminfo for portability, and raw mode for immediate keystroke handling demystifies a lot of otherwise-confusing behavior: why some old or obscure terminal types render TUI apps incorrectly, why a crashed TUI app can leave your terminal in a broken state, and why building a properly portable full-screen terminal application is considerably more involved than it might first appear.