Skip to content

Environment and detection

Status: Convention. Nothing on this page is specified by a standard; all of it is what programs actually do.

An application learns about its terminal from four sources, in decreasing order of reliability: the terminfo database, direct queries, environment variables, and guesswork.

TERM and terminfo

TERM names a terminfo entry. ncurses reads the entry and exposes capabilities such as colors, cup, smkx, Tc, Smulx through tput(1), infocmp(1), and the curses API.

TERM Set by Notes
xterm-256color xterm, VTE, Konsole, WezTerm, iTerm2, Apple Terminal, xterm.js hosts, WSL The lowest common denominator; describes xterm, not the emulator
xterm PuTTY, mintty, many SSH defaults 8 colors in the database, although the emulator does more
xterm-kitty kitty Ships with kitty; missing on remote hosts unless copied
xterm-ghostty Ghostty Same
foot, foot-extra foot Same
alacritty Alacritty Same
wezterm WezTerm (optional) Default remains xterm-256color
contour Contour Same
rxvt-unicode-256color rxvt-unicode
st-256color st
tmux-256color, screen-256color tmux, screen Describe the multiplexer, not the outer terminal
linux Linux console
dumb pipes, some CI No cursor addressing

The recurring failure is a terminfo entry that is absent on a remote host, which produces tput: unknown terminal and broken clear, less, and vim. Emulators with custom TERM values document how to copy the entry (infocmp -x | ssh host tic -x -) or fall back to xterm-256color.

TERM cannot identify the emulator. xterm-256color is claimed by a dozen programs with different feature sets.

Environment variables

Variable Set by Values
COLORTERM Most emulators truecolor or 24bit; the only widely honored truecolor signal; not propagated by SSH by default
TERM_PROGRAM Apple Terminal (Apple_Terminal), iTerm2 (iTerm.app), WezTerm, Ghostty, VS Code (vscode), mintty, tmux (tmux), Hyper, Tabby, Warp (WarpTerminal) Emulator identity; unset by xterm, VTE, kitty, Alacritty, foot, Windows Terminal
TERM_PROGRAM_VERSION Same Free-form version string
WT_SESSION, WT_PROFILE_ID Windows Terminal Session GUID; the practical Windows Terminal detector
KITTY_WINDOW_ID, KITTY_PID kitty
GHOSTTY_RESOURCES_DIR Ghostty
WEZTERM_PANE, WEZTERM_EXECUTABLE WezTerm
ALACRITTY_WINDOW_ID Alacritty
KONSOLE_VERSION, KONSOLE_DBUS_SESSION Konsole
VTE_VERSION VTE terminals Decimal MMmmpp; note it identifies the library, not the front end
TERM_SESSION_ID Apple Terminal, iTerm2
ITERM_SESSION_ID, LC_TERMINAL iTerm2 LC_TERMINAL survives SSH when the client forwards LC_*
TMUX, TMUX_PANE tmux Presence means a multiplexer sits between the application and the emulator
STY screen Same
ZELLIJ zellij Same
SSH_TTY, SSH_CONNECTION sshd The emulator is remote; environment variables describe the client only if forwarded
NO_COLOR, FORCE_COLOR, CLICOLOR Users, CI Application-level conventions; see no-color.org
LANG, LC_ALL, LC_CTYPE Login Determine whether the application encodes UTF-8; see Encoding

Variables are inherited, not live. They describe the terminal that started the shell, which is wrong after ssh, tmux attach from a different emulator, or su. Treat them as hints and confirm with queries.

Queries

Question Query Page
Is a terminal there at all? DA1 CSI c Queries
Which emulator and version? XTVERSION CSI > 0 q XTVERSION
Is mode N supported / set? DECRQM CSI ? N $ p Modes
What does terminfo say, without a database? XTGETTCAP DCS + q … ST XTGETTCAP
Kitty keyboard? CSI ? u Kitty keyboard
Sixel? DA1 feature 4; XTSMGRAPHICS Sixel
Kitty graphics? APC G i=31,s=1,v=1,a=q,t=d,f=24 ; AAAA ST Kitty graphics
Background dark or light? OSC 11 ; ? ST Colors
Cell size in pixels? CSI 16 t Window operations
Current cursor column (width test)? CSI 6 n Width

Send optional queries first and DA1 last in one write; DA1's reply marks the end. Always use a timeout; never block. Under tmux the answers describe tmux.

Guesswork

Applications that cannot query (non-interactive output, logging libraries) fall back to heuristics: COLORTERM for truecolor, TERM containing 256color, TERM_PROGRAM for hyperlinks and images, NO_COLOR to disable everything. Libraries such as supports-color and Python's rich encode these heuristics; they are wrong in the same predictable ways (SSH loses COLORTERM, tmux hides the outer terminal).

Probe

env | grep -E '^(TERM|COLORTERM|TERM_PROGRAM|TERM_PROGRAM_VERSION|WT_SESSION|KITTY_|GHOSTTY|WEZTERM|VTE_VERSION|TMUX|STY|ZELLIJ|SSH_TTY)'
infocmp -x1 | grep -E '(colors|Tc|RGB|Smulx|Setulc|Sync|Ss|Se|E3|bce)'
tools/query version da1

Sources