Skip to content

Sixel

Status: DEC. Defined for the VT240 and VT330/VT340; xterm is the reference software implementation.

Sixel encodes a bitmap as printable ASCII, six vertical pixels per byte, with a palette of color registers. It is the oldest image protocol in use and the only one with a DEC manual behind it.

Syntax

DCS Pa ; Pb ; Ph q sixel-data ST
Parameter Meaning
Pa Pixel aspect ratio selector: 0, 1, 5, 6 → 2:1; 2 → 5:1; 3, 4 → 3:1; 7, 8, 9 → 1:1. Emulators generally ignore it and use 1:1
Pb Background: 0 or 2 → pixels with no data take the background color; 1 → they are left unchanged (transparent)
Ph Horizontal grid size; ignored by emulators

Data grammar

Element Form Meaning
Sixel byte ?–~ (0x3f–0x7e) Subtract 0x3f; each of the six bits is one pixel, LSB at the top
Repeat ! Pn byte Emit the byte Pn times
Color select # Pc Use register Pc for following bytes
Color define # Pc ; Pu ; Px ; Py ; Pz Set register Pc; Pu=1 HLS (Px hue 0–360, Py lightness, Pz saturation), Pu=2 RGB with components 0–100
Carriage return $ Return to the left edge of the current six-pixel band
New line - Move to the next band
Raster attributes " Pan ; Pad ; Ph ; Pv Aspect numerator/denominator and image width/height in pixels; lets the terminal allocate the area first

Registers default to 16 on a VT340; emulators allow 256 or more and report the number through XTSMGRAPHICS. Colors are percentages, so #0;2;100;0;0 is pure red.

DECSDM, mode 80 — Disputed

The VT330/VT340 manual defines CSI ? 80 h as Sixel Display Mode: when set, the image is displayed as on a graphics terminal without scrolling, at the top left; when reset, sixel output scrolls with text and the cursor moves below the image.

xterm implemented the mode with the opposite polarity until release 369, treating set as "scrolling enabled". Since 369 xterm follows the manual, and the change log records the correction1. Emulators that copied the earlier xterm behavior are still in the field; applications should not rely on mode 80 and should instead leave it at the default and use ?8452 to control cursor placement.

Mode 8452

CSI ? 8452 h: after an image, leave the cursor on the same row to the right of the image, instead of on the next row at column 1. xterm extension, adopted by several emulators.

Mode 1070

CSI ? 1070 h (default set in xterm): each sixel image uses a private palette; reset shares one palette across images, as the VT340 did.

XTSMGRAPHICS

CSI ? Pi ; Pa ; Pv S

Pi = 1 for color registers, 2 for sixel geometry, 3 for ReGIS geometry. Pa = 1 read, 2 reset to default, 3 set to Pv, 4 read maximum. The reply is CSI ? Pi ; Ps ; Pv S with Ps = 0 success. Sending CSI ? 2 ; 1 S returns the largest image size the terminal accepts.

Behavior

The image is painted starting at the cursor position. Rows the image covers are marked as containing graphics; text written later overprints or is overprinted depending on the emulator. Scrolling the row scrolls the image strip with it; erasing the cells removes that strip in most emulators.

Sixel data for a large image is long. An emulator must parse it incrementally, and applications on slow links should size images with the raster attribute so the terminal can reserve space before data arrives.

Probe

A 6×6 red square with a blue diagonal band, no external tools:

printf '\033P0;1;0q"1;1;6;6#0;2;100;0;0#1;2;0;0;100#0!6~-#0!6~\033\\\n'

Query the maximum geometry and register count:

stty -echo -icanon min 0 time 5
printf '\033[?2;4S\033[?1;1S'; dd bs=64 count=1 2>/dev/null | cat -v; echo
stty sane

Convert a real image with libsixel: img2sixel photo.png. Or:

python3 -c '
import sys
w,h=12,12
out="\033P0;1;0q\"1;1;%d;%d#0;2;0;80;0"%(w,h)
for band in range(0,h,6):
    out+="#0"+"~"*w+("-" if band+6<h else "")
sys.stdout.write(out+"\033\\\\\n")'

Sources

Compatibility

Feature support by terminal. Imported claims have not been reverified; unknown is not unsupported.
Feature / stable ID Alacritty Apple Terminal ConPTY (conhost) Contour DomTerm foot Ghostty iTerm2 kitty Konsole mintty mlterm PuTTY Revenant RLogin st tmux rxvt-unicode VTE wayst WezTerm Windows Terminal xterm xterm.js
Sixel
dcs-sixel
UnsupportedImported · unverified Unknown Unknown SupportedImported · unverified SupportedImported · unverified SupportedImported · unverified UnsupportedImported · unverified SupportedImported · unverified UnsupportedImported · unverified SupportedImported · unverified SupportedImported · unverified SupportedImported · unverified Unknown Unknown SupportedImported · unverified Unknown SupportedImported · unverified Unknown SupportedImported · unverified Unknown SupportedImported · unverified SupportedImported · unverified SupportedImported · unverified SupportedImported · unverified
XTSMGRAPHICS graphics attributes
csi-xtsmgraphics
Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown Unknown

  1. xterm change log, patch 369. ↩