XTVERSION — Report terminal name and version (CSI > Pp q)
Ask the terminal for a human-readable name + version string — the modern alternative to DECDA for feature detection in tools like Helix, Zellij, Neovim.
Byte forms
Every common string-literal form so you can paste-and-search either direction.
\x1b[>0q (query) reply: \x1bP>|<name> <version>\x1b\\\033[>0q\e[>0qESC [ > Pp q → DCS > | <text> ST1b 5b 3e ... 71Description
Sends a Tertiary Device Attribute (TDA) query in xterm's extended form. The `>` prefix flips the final byte `q` from DECSCA (character protection) to XTVERSION; `Pp` is reserved (always emit `0`) and exists only for forward compatibility. The terminal replies with a DCS-framed string identifying itself: `DCS > | <name> <space> <version> ST` — e.g. `\x1bP>|XTerm(370)\x1b\\`, `\x1bP>|kitty 0.32.2\x1b\\`, `\x1bP>|WezTerm 20240203\x1b\\`, `\x1bP>|ghostty 1.0.0\x1b\\`. The terminator is ST (`\x1b\\`), occasionally BEL (`\x07`) for legacy emitters. This sequence has effectively replaced DECDA (`\x1b[c`) for feature detection — DECDA's terminal-ID numbers (61/62/63 = VT100/220/320) were exhausted in the 1990s and don't represent modern features at all. XTVERSION is the load-bearing query behind every TUI that branches on `kitty` vs `WezTerm` vs `iTerm2` to enable kitty graphics, OSC 1337 features, or sixel. Round-trip is fast (synchronous on Unix terminals; non-blocking polling works for ConPTY). If no reply arrives within ~200 ms, assume a primitive terminal that doesn't implement XTVERSION.
Spec citation: xterm-ctlseqs (Tertiary DA / XTVERSION)
Parameters
| Pp | Reserved. Always emit `0`. The presence of any value distinguishes XTVERSION from CSI > q (no param) which is also valid. |
Examples
# Print whichever terminal name comes back, then disambiguate:\nprintf '\033[>0q'\nread -rd '\\' reply\necho "$reply" # e.g. \x1bP>|kitty 0.32.2import sys, termios, tty, select\nsys.stdout.write('\x1b[>0q'); sys.stdout.flush()\n# Read DCS-framed reply: starts with \x1bP and ends with \x1b\\fmt.Print("\x1b[>0q")\n// scan stdin for DCS > | ... ST framing\n// branch: strings.HasPrefix(name, "kitty") → enable kitty graphicsprocess.stdout.write('\x1b[>0q')\n// process.stdin gets back a DCS-framed text like \x1bP>|WezTerm 20240203\x1b\\fputs("\x1b[>0q", stdout); fflush(stdout);\n/* read DCS payload, switch on substring 'kitty' / 'xterm' / 'WezTerm' */Terminal support
- xterm
- yes
- Linux console (fbcon)
- no
- macOS Terminal.app
- no
- iTerm2
- yes
- Windows Terminal
- yes
- cmd.exe / ConPTY
- no
- kitty
- yes
- alacritty
- no
- WezTerm
- yes
- Ghostty
- yes
- GNOME Terminal
- partial
- Konsole
- yes
- tmux
- no
- GNU screen
- no
| xterm | Linux console (fbcon) | macOS Terminal.app | iTerm2 | Windows Terminal | cmd.exe / ConPTY | kitty | alacritty | WezTerm | Ghostty | GNOME Terminal | Konsole | tmux | GNU screen |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| yes | no | no | yes | yes | no | yes | no | yes | yes | partial | yes | no | no |