Field Report · Terminal Rendering

Drawing in the Terminal, 2026

What replaced libcaca — and the quiet graphics renaissance that came with it.

COMPILED BY CLAUDE (OPUS 4.8)  ·  2026-06-18  ·  SOURCES: GITHUB + NPM (LIVE)

The one-line answer

The modern libcaca is chafa.

But the bigger truth is that the terminal stopped pretending. The frontier moved from "approximate a picture with characters" to real pixels over a wire protocol (Kitty / Sixel), with fancy Unicode glyphs as the graceful fallback. chafa wins precisely because it spans the whole ladder. libcaca / aalib are now history exhibits, not tools to build on.


1

The lineage

aalib (1997, monochrome ASCII) → libcaca (2002, "Colour ASCII Art" + a cacaview/img2txt CLI) defined the genre: take an image, map cells to characters by luminance, dither in 16 colors. Brilliant for its era — and effectively frozen since. libcaca's last release is v0.99.beta20 from 2021; the repo's own description is a literal 💩 emoji. It still ships in distros, but nobody starts new work on it.

What changed underneath it: 24-bit truecolor went mainstream, Unicode kept minting denser block glyphs, GPUs got into terminals, and three image protocols matured. The successors split along those lines.

2

Image → terminal: the direct descendants

If you mean "a tool/library that turns a PNG/GIF/video into terminal output" — the img2txt lineage — this is the table. Click any column header to sort.

ProjectLangStarsUpdatedWhat it is
chafa the answerC4,9362026-06-09CLI + libchafa. Emits Kitty/Sixel/iTerm2 and the richest char art (incl. octants). The drop-in modern libcaca.
notcursesC4,5782026-05-18"Blingful" character-graphics + full-screen TUI library. The library-shaped successor; blits images/video.
timgC++2,6682026-02-19Image and video/GIF viewer. Kitty/Sixel/iTerm2 + half-blocks. Excellent quality.
viuRust3,2182025-12-15Simple, fast viewer (iTerm/Kitty native). Built on the viuer crate you can embed.
catimgC1,5592026-04-07"Insanely fast." Half-block Unicode, zero fuss.
tivC++1,6812026-06-03Clever per-cell glyph selection with RGB. Pure-Unicode, very portable.
ascii-image-converter slowingGo3,3772024-04-14ASCII + braille art focus. Popular, but last release 2022 — momentum fading.
ueberzugppC++1,2912026-05-18Different trick: overlays true images above a TUI. Powers file-manager previews (ranger/lf/yazi).
libcaca legacyC6752026-04-19The original. Maintenance-only. Respect it; don't build on it.

★ counts & "updated" are pulled live from GitHub.

3

The two things that actually changed

A · Graphics protocols — the real "modern rendering"

Terminals can now stream actual raster images into the grid. Three protocols, in rough order of momentum (hover a card & click to read the spec):

↗

Kitty Graphics

The emerging standard. PNG/animation, placement, z-index. Supported by kitty, WezTerm, Ghostty, Konsole. Target this first.

↗

Sixel

1980s DEC format, resurgent. The broad-compat fallback: xterm, foot, mlterm, WezTerm, Konsole, Windows Terminal.

↗

iTerm2 inline

Base64-an-image escape. macOS/iTerm2 + WezTerm. Simple; narrower reach.

You rarely implement these by hand — you let chafa, timg, terminal-image or a TUI lib probe the terminal and pick. To actually see pixels you need a capable emulator (see §6).

B · The character-cell resolution ladder kept climbing

When there's no protocol (SSH to a basic box, CI logs, a retro vibe), you fake pixels with block glyphs. Unicode keeps adding denser ones — each step doubles the "sub-pixels" per character cell:

Glyph setSub-cellsSinceNote
ASCII (luminance ramp)1 (brightness)1963the @%#*+=-:. aesthetic
Half blocks ▀2×1legacyfg+bg = 2 color pixels/cell
Quadrants ▟2×2legacy4 sub-cells
Sextants2×3Unicode 13 (2020)"Symbols for Legacy Computing"
Octants newest2×4Unicode 16 (2024)8 sub-cells — chafa supports them
Braille ⠿2×4 dotsUnicode (Braille)monochrome but dense — great for line art / plots

The edge today: chafa's support for octants (2×4, Unicode 16) is the genuinely-latest move in pure-character rendering — finer grayscale than the sextants everyone copied in 2021. For monochrome density (and terminal plots), braille remains the portable trick.

4

The npm angle (a whole separate universe)

Node didn't inherit the C lineage — it grew its own, and the scale is wild. Monthly npm downloads beside GitHub stars; both update live. (For calibration, chalk alone pulls ~1.8 billion/mo.) Sortable.

PackageRoleDownloads/moStars
ink node leaderReact-for-CLIs TUI framework16.5M/mo39.0k
@xterm/xtermterminal emulator for the web (VS Code's)11.4M/mo20.8k
blessed staleclassic full TUI lib (unmaintained since '24)5.9M/mo11.9k
terminal-kitbatteries-included terminal toolkit (+images)1.2M/mo3.4k
terminal-image imagesPNG/GIF → terminal (iTerm/Kitty + fallback)158k/mo1.1k
figletFIGfont big-ASCII text8.3M/mo—
gradient-stringgradient-colored text8.8M/mo—
cfontsblocky banner fonts2.0M/mo—
drawillebraille drawing canvas2.2k/mo—
node-sixelSixel encode/decode (powers xterm.js' addon)24.5k/mo33

downloads & ★ are pulled live.

Read of the npm scene: for building a UI, ink is the runaway winner (React mental-model). blessed is everywhere by inertia but effectively abandoned — prefer ink or terminal-kit for new work. For just putting an image on screen, terminal-image is the clean pick. And @xterm/xterm is a different beast — it's the emulator you embed in a web app.

5

The wider renaissance: modern TUI frameworks

Here's the twist — if by "modern libcaca" you mean "how do people draw rich things in a terminal now," the center of gravity isn't an image library at all. It's the new wave of app frameworks, each massively starred. Sortable.

LangFrameworkStarsUpdatedMental model
GoBubble Tea43.2k2026-06-15Elm architecture (model/update/view); the "Charm" stack
GoLip Gloss11.4k2026-06-15style & layout definitions for Bubble Tea
RustRatatui21.1k2026-06-18immediate-mode: redraw the whole UI each frame
PythonRich56.6k2026-06-15rich-text renderables (tables, syntax, progress)
PythonTextual36.3k2026-05-27web-inspired app TUI; also runs in a browser
NodeInk39.0k2026-06-17React components + flexbox (Yoga)
CNotcurses4.6k2026-05-18ncurses successor with multimedia blitting

★ & "updated" are pulled live.

These are why the terminal feels alive again in 2026 — installers, AI coding agents, dashboards, git UIs. Several now speak "Mode 2026" (DEC synchronized output) to kill flicker; Ink v6.7+ and Bubble Tea v2 adopted it. Most embed an image lib (ratatui-image, textual-image, ink-image) when they need a real picture.

6

The enablers: terminals that can actually draw

None of the pixel stuff matters if the emulator can't render it. Your renderer is only as good as the terminal under it (hover & click each):

↗

Ghostty momentum

Native Metal on macOS → 120Hz/ProMotion, adaptive sync, power-efficient. Kitty protocol. The 2025–26 darling.

↗

kitty

GPU-accelerated; origin of the Kitty graphics protocol. The reference implementation.

↗

WezTerm

The completist: the only terminal that speaks all three image protocols (Kitty + Sixel + iTerm2).

↗

Konsole

KDE's workhorse — Kitty + Sixel. Mature, configurable, a solid Linux default.

↗

foot

Lean, fast Wayland-native terminal with Sixel. The minimalist Linux pick.

↗

Apple Terminal avoid

No image protocol, and still no truecolor in 2026. The lowest common denominator — test your fallbacks here.

7

My take & guidance

If you just want to throw an image in the terminal

# chafa auto-detects kitty/sixel/iterm2 and falls back to unicode. that's it.
chafa image.png
chafa -f sixel movie.gif            # force a protocol
chafa --symbols octant photo.jpg    # force fanciest char art (Unicode 16)

One tool, every output mode, actively developed. Don't overthink it — chafa it is.

If you're embedding in an app

Link libchafa (C/FFI) for image→cells. For a whole UI, use your language's framework — and let it own rendering rather than hand-rolling escape codes:

go get github.com/charmbracelet/bubbletea   # Go
cargo add ratatui                            # Rust
pip install textual                          # Python
npm i ink react                              # Node
npm i terminal-image                         # Node, images only

Where the puck is going: bet on the Kitty graphics protocol as primary, Sixel as fallback, octant/half-block Unicode as the floor. Ghostty's GPU-native rise is dragging "real graphics in the terminal" from novelty to expectation. The good news: chafa / timg / terminal-image already encode that exact ladder, so you usually inherit it for free.

The potholes nobody warns you about:  (1) tmux & SSH swallow image protocols unless you enable passthrough.  (2) Cell aspect ratio isn't 1:1 (~1:2 tall) — naive rendering squashes images.  (3) Terminal detection is a swamp — never assume; probe (or lean on a lib).  (4) Scrollback + images interact weirdly.  (5) Test on Apple Terminal to see your true fallback.

The verdict in one breath

chafa is the modern libcaca — full stop. But "terminal rendering in 2026" is a much bigger story: GPU terminals + Kitty/Sixel protocols for real pixels, the octant/braille Unicode ceiling for fallback, and a per-language TUI-framework boom (Bubble Tea / Ratatui / Textual / Ink) where most actual "drawing" now happens. libcaca and aalib walked so this could run. 🫡

8

Special cases: shells, multiplexers & the silicon

Three things that aren't renderers — but they decide whether your rendering is fast, or works at all. (You asked for the asterisks; here they are.)

A · Shells & prompts — they gate your latency, not your pixels

A "slow terminal" is usually a slow prompt. These are shell config, not renderers, but they're where the lag lives. Sortable.

ToolStarsUpdatedWhat it is & the catch
starship modern pick58.4k2026-06-15Rust, cross-shell, fast. Instant in most repos; only stalls in giant ones.
powerlevel10k54.5k2026-06-15Zsh theme with instant-prompt (<10ms); fastest in huge git repos.
oh-my-zsh188k2026-06-15Zsh config framework, not a renderer. 300+ plugins → can bloat startup; prune to stay snappy.

★ & "updated" pulled live.

Pick: starship for cross-shell + speed; powerlevel10k if you live in zsh and want instant-prompt; oh-my-zsh is fine — just pair it with a fast theme and trim plugins.

B · Multiplexers — the protocol-killers

Run inside tmux or zellij and your image protocols can vanish — the multiplexer sits between the app and the terminal, so Kitty/Sixel output gets mangled unless you turn on passthrough.

↗

tmux

The classic. Needs set -g allow-passthrough on for graphics; older builds still garble Sixel/Kitty.

↗

zellij

Modern Rust workspace — panes, layouts, plugins. Friendlier defaults, but still verify protocol passthrough.

Gotcha: if images render fine bare but break "inside the terminal," suspect tmux/zellij (or SSH) eating the escape sequence — enable passthrough before blaming your renderer.

C · The silicon — GPU is baseline, TPU isn't a thing

GPU acceleration is now standard, not a differentiator; the interesting axis is the rendering API. Ghostty's custom Zig engine even hits ~2 ms key-to-screen. Sortable.

TerminalLangGPU APIStars
Ghostty fastestZigMetal · OpenGL/Vulkan56.7k
AlacrittyRustOpenGL (the OG)64.6k
kittyC · PythonOpenGL—
WezTermRustOpenGL / WebGPU—
WarpRustGPU + agentic62.0k

★ pulled live.

So is there a TPU/NPU-accelerated terminal? No — and there's no reason for one. A terminal draws a grid of glyphs plus the odd raster blit; that's trivial for any GPU. TPUs/NPUs are matrix-multiply units built for ML, not text/raster rendering. The only "AI silicon" angle is Warp's agentic features (LLMs for suggestions/commands) — compute for behavior, not for drawing. "3D terminals" remain novelties, not a category.


★

Sources & method

Star counts & "updated" dates are fetched live from the GitHub REST API; npm download counts from the npm registry API. A scheduled GitHub Action re-bakes data.json daily, so the tables stay current with no per-visitor rate limits.

Background reading: chafa — hpjansson.org · Terminal Graphics Protocols — Akmatori · Kitty graphics protocol spec · rothgar/awesome-tuis · Bubble Tea vs Ratatui (2026) · lnqs/textual-image · Best terminal for Mac 2026