Satori
🗒️ vercel/satori converts an element tree (JSX with a CSS subset) into SVG, and @resvg/resvg-wasm rasterises that SVG to PNG. The whole chain is pure JS plus WASM: no native .node modules, so it runs under Smart App Control with the signed node.exe. About 14k stars, 4.5M npm downloads a week, very active (three releases on 2026-10-15). In Meme Generation for Coding Agents it is the primary renderer for captions.
Links
Description
- Why it fits. Fonts are loaded as ArrayBuffers, so any TTF with Polish glyphs works (Anton, Impact, Noto Sans static). A tofu detector (
loadAdditionalAsset) can flag exactly the missing glyphs and refuse to render. In the proof of concept: a render took 0.2-0.4 s (about 0.55-0.65 s per meme with Node start-up), a 12-frame 480x480 GIF was 175 KB with Polish intact, and auto-fit of long captions worked with about seven calls per caption box. - Pitfalls found by testing:
@fontsourcelatinandlatin-extsubsets registered under the same family name fail silently: Satori uses only the first file and Polish letters become empty boxes. Register them under distinct names, or use one full TTF.- Variable fonts crash Satori (the Noto variable TTF raised “reading 256”); use static files.
- On Windows import packages with
pathToFileURL(...).href; rawC:\paths fail withERR_UNSUPPORTED_ESM_URL_SCHEME. Import Satori’s ESM entry and resvg-wasm’sindex.mjs, then callinitWasmwith the.wasmbytes. - Line-height 1.12 made the ogoneks in “GĘŚLĄ” collide with accents on the next line; 1.32 fixes it.
- There is no built-in auto-fit, and resvg-wasm has had no release since 2024-03 (the slow step, about 0.2-0.3 s). Satori itself is pre-1.0 and ships fast, so pin the version.
Download or use
In the skill folder: npm init -y && npm install --ignore-scripts satori@0.57.2 @resvg/resvg-wasm@2.6.2 (Node 18 or newer, tested on 24). Add OFL fonts such as Anton-Regular.ttf from github.com/google/fonts/ofl/anton. A render script is about 60-80 lines: load fonts as Buffers, build the element tree per template, satori() → Resvg → PNG. Satori 0.58 and 0.59 came out hours after the test and were not tried.
Reasoning for
I want a meme renderer that adds no native binary, does not need a browser and lets me prove Polish glyph coverage. The alternative that also works is Playwright with the signed Edge or Chrome (heavier, 7-14 s cold start; never run playwright install, its downloaded ffmpeg was blocked). I will pin Satori and re-run a Polish self-test (Zażółć gęślą jaźń) before every bump.
Alternatives considered
- Pillow script: Polish-correct with a TTF, the simplest fallback, and its
.pydfiles load under Smart App Control. - Playwright / Playwright MCP: full CSS and an installed browser, but slow and heavy.
@vercel/og: built on Satori for OpenGraph images; same engine, fewer knobs.- ffmpeg
drawtext: no wrapping andfont=fails on Windows; ASS subtitles are the better ffmpeg path.
Resources
- 🔗 github.com/vercel/satori · resvg-js (the
@resvg/resvg-wasmpackage) - 📖 Related: Meme Generation for Coding Agents · OpenClaw Meme Maker · Slack GIF Creator · Memegen · Playwright MCP · Claude Code
Template: tool