Skip to main content
ansicode
Terminal

cmd.exe / ConPTY — ANSI escape code support

cmd.exe is the legacy Windows Command Processor shipping in every release since Windows NT 3.1 (1993). It's a shell, not a terminal — when you launch it, Windows hands its stdio to a console host that does the actual rendering: conhost.exe on Windows 10 and earlier, ConPTY (the in-kernel pseudo-console) on Windows 10 1809+ and Windows 11. The historical gap most developers hit is ANSI escape parsing: vintage conhost.exe ignored `\x1b[31m` and rendered the bytes as literal text. The fix landed in Windows 10 1511 (Nov 2015) behind an opt-in `ENABLE_VIRTUAL_TERMINAL_PROCESSING` flag passed to `SetConsoleMode`, became the default for most apps in Windows 10 1709 (Oct 2017), and was rebuilt around ConPTY in 1809 (Oct 2018) so that legacy Win32 console API calls (`SetConsoleTextAttribute`, `WriteConsoleW`) are now translated *into* VT bytes on the way out.

In 2026 practice: every supported Windows version parses xterm-ctlseqs by default. The remaining cmd-specific quirks are the BAT-file `$E` prompt syntax for embedding ESC, the `chcp 65001` codepage incantation needed for non-ASCII text, and the ConPTY translation lossiness — Win32-console-only apps don't always survive the round-trip cleanly. cmd.exe itself emits nothing on its own; everything you see colourised in a cmd window came from a child process via VT bytes.

Last updated

Feature support

How this terminal scores against the 15 features tracked in the site-wide support matrix. Click any feature name to see the full row across every terminal.

  • 8 basic colors (30–37 / 40–47)SGR 30–37 foreground, 40–47 background.
    yes
  • Bright (aixterm) colors (90–97 / 100–107)aixterm SGR extension.
    yes
  • 256-color palette (38;5;n / 48;5;n)xterm 256-color extension.
    partial
  • 24-bit truecolor (38;2;r;g;b)16.7M direct RGB. Set $COLORTERM=truecolor.
    partial
  • Italic (SGR 3)Italic text attribute.
    no
  • Styled underlines (4:1–4:5)Curly/dotted/dashed underline styles.
    no
  • Strikethrough (SGR 9)Horizontal line through text.
    no
  • OSC 8 hyperlinksInline clickable URIs.
    no
  • Alt screen (?1049h)Full-screen app buffer.
    partial
  • Mouse tracking (SGR ?1006)Mouse click/drag events.
    partial
  • Bracketed paste (?2004)Pasted text wrapped in ESC[200~/ESC[201~.
    yes
  • Focus events (?1004)ESC[I on focus in, ESC[O on focus out.
    no
  • Sixel graphicsDEC sixel inline raster images.
    no
  • Kitty graphics protocolPNG/RGB inline images, animations.
    no
  • Synchronized output (?2026)Atomic frame updates to avoid tearing.
    no

Sequences that work here

Canonical reference pages for the escape sequences this terminal handles cleanly. Each links to a full page with byte forms, citations, and per-language examples.

Quirks & version notes

Per-terminal caveats you'll want to know before relying on a sequence in production.

ENABLE_VIRTUAL_TERMINAL_PROCESSING — the legacy opt-in flag
Before 1709, console apps had to opt in to VT parsing by calling `SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), ENABLE_VIRTUAL_TERMINAL_PROCESSING | ENABLE_PROCESSED_OUTPUT)`. Python's `colorama.just_fix_windows_console()` (since v0.4.6) and `pwsh.exe`'s prompt setup do this for you; raw `python.exe` / `node.exe` / `go run` on 1809+ get VT enabled implicitly because ConPTY is in the pipeline. Bare C: `#include <windows.h>` + `SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), 0x0001 | 0x0004)`. PowerShell: `[Console]::OutputEncoding = [System.Text.Encoding]::UTF8` + nothing else needed. If you're shipping a CLI that must work on Win7 / Server 2008 R2, fall back to the `colorama`-style Win32-API path.
ConPTY translation is lossy — Win32-console quirks survive
Since 1809, every cmd window is fronted by ConPTY: it owns a screen buffer, runs the parser, and emits VT bytes upstream. Legacy programs that still call `WriteConsoleOutput` or query screen-buffer state through `GetConsoleScreenBufferInfo` work by ConPTY synthesising responses. Two known lossy cases: (1) `WriteConsoleOutput` with non-default attributes is approximated to the nearest VT SGR — sub-cell precision is dropped; (2) bracketed-paste mode bytes can leak into apps that didn't request them, because ConPTY can't tell which child process expects which DEC private mode (microsoft/terminal#3866). Workaround: detect ConPTY via `IsConsoleHandle + GetConsoleMode` returning `ENABLE_VIRTUAL_TERMINAL_INPUT` and emit only modern VT.
`prompt $E[1;31m…$E[0m` — embedding ESC in cmd.exe prompts
cmd.exe's `prompt` builtin expands `$E` to a literal `\x1b` byte, so `prompt $E[1;31m$P$E[0m$G` paints the working-directory prompt red. Set it permanently via `setx PROMPT "$E[1;31m$P$E[0m$G"`. In BAT scripts you can also use `for /F %%a in ('echo prompt $E ^| cmd') do set ESC=%%a` to capture an ESC byte into a variable. Modern PowerShell users use `$PSStyle.Foreground.Red` instead; cmd users have no native colour API, only this prompt-substitution trick.
`chcp 65001` for UTF-8 — and the EOF gotcha
cmd.exe defaults to the OEM codepage (cp437 in US English locale), so emoji and most non-ASCII text in coloured output render as mojibake. `chcp 65001` switches the active codepage to UTF-8; persist it with `setx /M PYTHONUTF8 1` (Python) or via `Settings → Time & Language → Language & Region → Administrative language settings → Change system locale → Beta: Use Unicode UTF-8` (Windows 10 1903+, machine-wide). The historical EOF gotcha: under cp65001 some C runtime versions read EOF prematurely on `getchar()` — fixed in MSVC v142+ but still bites mingw-built binaries. SGR escape bytes themselves are codepage-insensitive (they're ASCII), so colour works on any codepage.
Truecolor: yes since 1709, but conhost.exe quantizes to 16
Windows 10 1709+ parses `\x1b[38;2;R;G;Bm` truecolor SGR. In Windows Terminal you get the actual 24-bit pixel; in legacy conhost.exe (the host you see when you launch cmd directly from `C:\Windows\System32\cmd.exe`, not via `wt.exe`) the truecolor value is quantized to the nearest of 16 console-palette colours. Apps that care should query `$COLORTERM=truecolor` (Windows Terminal sets it; conhost.exe doesn't) or — better — emit 256-indexed colour as the safer baseline. ConPTY on 1809+ passes the truecolor bytes through unchanged; the quantisation happens at the rendering layer above, not in the parser.
$TERM is unset — detect via `OS=Windows_NT`
cmd.exe doesn't set `$TERM` — terminfo-based detection (`tput colors`, `infocmp`) silently fails. Instead, cross-platform CLIs check `process.platform === 'win32'` (Node), `os.name === 'nt'` (Python), `runtime.GOOS === "windows"` (Go), `cfg!(windows)` (Rust). For finer-grained "running under Windows Terminal vs raw conhost" detection, look at `$WT_SESSION` (set by Windows Terminal only) or `$TERM_PROGRAM=Windows_Terminal`. Bare cmd / conhost has neither, just `OS=Windows_NT`. Inside WSL the picture flips: there `$TERM` is set normally by the Linux shell and the Windows host is invisible.

Citations

Other terminals with landing pages