kittyhtml
Render HTML to an image and display it inline in a graphics-capable terminal (Kitty, WezTerm, Ghostty, iTerm2).
This is not a headless browser. It's a thin CLI that pipes HTML through Blitz — a Rust HTML/CSS engine (Stylo + Taffy + Parley + Vello) — to a PNG, then emits the Kitty graphics protocol or iTerm2 inline-image protocol on stdout. Headless CPU rasterization, no GPU required.
Built for AI agents that have something nice to show you — a styled report, a small table, a card — without taking over your screen with a browser.
Install
Or one-shot, no install:
Requires Node 20+. The native renderer ships as a prebuilt N-API binary per platform (macOS arm64, Linux x64). No Rust toolchain required at install time.
Use
kittyhtml --demo # bundled demo page echo '<h1>hi</h1>' | kittyhtml --width 400 kittyhtml report.html --scale 2 -o report.png # write PNG to file
Options
| flag | default | description |
|---|---|---|
--width N |
800 |
viewport width in CSS px |
--height N |
auto-fit | fixed canvas height |
--scale N |
1 |
pixel ratio (try 2 for retina-sharp text) |
--background CSS |
— | fill canvas before painting, e.g. #fff
|
--format auto|kitty|iterm2 |
auto |
output protocol; auto-detect from $TERM/$TERM_PROGRAM
|
--out, -o PATH |
— | write PNG to file (use - for raw PNG on stdout) |
--demo |
— | render the bundled demo page |
As a library
import { renderHtml, encode } from 'kittyhtml'; const png = await renderHtml('<h1>hello</h1>', { width: 400, scale: 2 }); process.stdout.write(encode(png, 'kitty'));
CSS
Blitz implements a serious subset of CSS — flexbox, grid, border-radius, box-shadow, web fonts, <img> tags, background: shorthand, max-width, native <ul> bullets, the things you'd expect. It's pre-alpha for general embedding but works well for our render-once use case. The full status matrix is at the Blitz repo.
Fonts
Noto Sans (regular, bold, italic, bold-italic) and Noto Sans Mono (regular, bold) are baked into the native binary as latin-subset TTFs. No system font dependency; renders identically across macOS and Linux. Reference them in HTML with font-family: 'Noto Sans', sans-serif and font-family: 'Noto Sans Mono', monospace.
Claude Code skill
A bundled skill lets Claude Code render output as a styled inline image when you ask for it as "kittyhtml" or "khtml". After a global install:
mkdir -p ~/.claude/skills cp -r "$(npm root -g)/kittyhtml/skill/kittyhtml" ~/.claude/skills/
Then in any Claude Code session: "give me this report as kittyhtml" — the agent will generate HTML and pipe it through this CLI. The skill is narrow on purpose; it only triggers on those keywords.
How agents should use it
If you're an AI agent on a host with kittyhtml installed and the user is on a graphics-capable terminal, pipe your HTML through it instead of dumping markup as text:
echo "$HTML" | kittyhtml --width 700 --scale 2
The image is one frame in the scrollback — no popups, no new windows.
Releasing
Releases publish via GitHub Actions using npm trusted publishing (OIDC, no long-lived token). The native binary is cross-compiled per platform and published as @kittyhtml/native-* packages, then the umbrella kittyhtml package selects the right one at install time.
npm version patch # or minor / major — bumps package.json and tags
git push --follow-tagsThe Publish to npm workflow fires on the v* tag, builds the native binaries on the matrix, and publishes everything with --provenance.