Skip to main content
ansicode

SGR 38;2;R;G;B — 24-bit truecolor foreground

Pick any of 16,777,216 foreground RGB colors directly.

Byte forms

Every common string-literal form so you can paste-and-search either direction.

\\x1b[\x1b[38;2;R;G;Bm
\\033[\033[38;2;R;G;Bm
\\e[\e[38;2;R;G;Bm
ESC [ESC [ 3 8 ; 2 ; R ; G ; B m
hex1b 5b 33 38 3b 32 3b ... 6d

Live preview

Rendered in your browser via the same tokeniser the decoder uses — no terminal needed.

warm 255,100,50 cool 100,200,255 violet 180,120,255

Description

SGR 38;2;R;G;B picks any of 16,777,216 foreground RGB colours directly — R, G, B each take 0–255. The background equivalent is \x1b[48;2;R;G;Bm. The shape comes from ITU-T T.416 ('Direct color'), adopted by xterm-ctlseqs as the de-facto truecolor SGR. Most parsers accept either the semicolon form (xterm legacy, widely supported) or the ECMA-48-compliant colon form \x1b[38:2::R:G:Bm — note the empty 4th sub-parameter, which T.416 reserves for a colorspace identifier. Emit semicolons by default; the colon form is safer only when you've verified the consumer handles it (some libraries reject the empty sub-param). Unlike SGR 30–37, the rendered colour is exactly the RGB you specified — not theme-dependent — which is the whole point of using truecolor.

Truecolor is the portability fault line in 2026. The detection signal apps should check is $COLORTERM=truecolor (or 24bit); without it, fall back to 256-palette quantization or to the basic 16, because not every stack renders the 24-bit bytes. Concrete pitfalls: (1) xterm parses 24-bit SGR unconditionally but doesn't export $COLORTERM=truecolor — libraries (chalk, colorama, click) that gate on the env var silently downgrade to 256-colour on xterm even though xterm itself accepts the bytes; (2) Apple Terminal.app has rendered truecolor since 10.7 Lion (2011) but also doesn't set $COLORTERM, with the same downgrade — set it manually in your shell init since the preference panel has no toggle; (3) tmux quantizes truecolor to 256-palette unless you add set -g default-terminal "tmux-256color" + set -ga terminal-overrides ",*256col*:Tc" (or the newer ,*:RGB) to ~/.tmux.conf; (4) Linux console / fbcon and Windows conhost.exe both quantize to 16; (5) GNU screen older than 5.0.0 (April 2024) silently quantizes — Ubuntu 22.04 ships 4.09, Apple's /usr/bin/screen ships v4.00.03 from 2006. Detection wrap-up: $COLORTERM=truecolor + infocmp $TERM | grep -E '(Tc|RGB)' is the safest test before emitting (see truecolor-detect).

Disable foreground with \x1b[39m — restores terminal default without touching background or attributes. The surgical close pair is \x1b[38;2;R;G;Bm…\x1b[39m; reaching for \x1b[0m clobbers everything else you set, and skipping the reset altogether bleeds colour into the user's prompt (see color-bleed). For an indexed palette that survives more multiplexer hops without quantization, see sgr-fg-256; for the 16 basic slots that render everywhere from Linux console to legacy conhost, see sgr-fg-basic; for the matching background side, see sgr-bg-truecolor. Truecolor is the right default on modern terminals (iTerm2, kitty, alacritty, wezterm, ghostty, Windows Terminal, recent gnome-terminal / konsole) but always pair it with the $COLORTERM check so the fallback path doesn't ship broken on stacks that quantize.

Spec citation: ITU-T T.416 / xterm-ctlseqs (Direct color)

Examples

bash
printf '\033[38;2;255;128;0morange\033[0m\n'
python
print('\x1b[38;2;255;128;0morange\x1b[0m')
go
fmt.Print("\x1b[38;2;255;128;0morange\x1b[0m\n")
javascript
console.log('\x1b[38;2;255;128;0morange\x1b[0m')
c
printf("\x1b[38;2;255;128;0morange\x1b[0m\n");

Used in

Real-world tools that emit this sequence — anchors the bytes to commands you've already used.

  • bat, delta (TrueColor themes)modern syntax themes assume 24-bit colour — fall back gracelessly without it
  • gh (GitHub CLI) — branded reds and greens
  • vim, neovim with `set termguicolors`switches all highlight groups from cterm to gui 24-bit colours
  • starship — branded prompt segments

Frequently asked

Short answers to the questions developers actually search for this sequence.

How do I detect whether the terminal supports 24-bit truecolor?
Check $COLORTERM — when set to truecolor or 24bit, the terminal advertises full 24-bit support. $TERM containing -direct (e.g. xterm-direct, tmux-direct) is the terminfo-side signal. When neither is set, fall back to 256-colour (\x1b[38;5;Nm) or the basic 16-colour palette. See the truecolor-detect pitfall.
Should I use ; or : between the 38;2 parameters?
Both work on most modern terminals. \x1b[38;2;255;100;50m (semicolons) is the xterm-style flat parameter list and is universally understood. \x1b[38:2::255:100:50m (colons with the colour-space slot) is the ITU T.416 / ECMA-48 sub-parameter form — kitty, alacritty, wezterm, ghostty accept it; older terminals do not. Prefer semicolons for portability.
Why do my smooth gradients look banded on macOS Terminal.app?
Terminal.app and the Linux console quantize truecolor down to their 256- or 16-colour palette before rendering, so adjacent slightly-different RGB values collapse onto the same swatch. The fix is renderer-side: detect lack of truecolor via $COLORTERM, and emit your gradient pre-quantized to 256 with bucket-aware steps instead. See truecolor-fallback-banding.

Terminal support

xterm
yes
Linux console (fbcon)
no
macOS Terminal.app
partial
iTerm2
yes
Windows Terminal
yes
cmd.exe / ConPTY
partial
kitty
yes
alacritty
yes
WezTerm
yes
Ghostty
yes
GNOME Terminal
yes
Konsole
yes
tmux
partial
GNU screen
partial

Related sequences

In the family cookbook

SGR cookbook · 4. Truecolor — `\x1b[38;2;r;g;b m`