Takumi

Rust rendering engine that turns JSX, HTML, and node trees into images without a headless browser

Library
npm
v2.10.0
2,815stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
81/100Excellent
Development Activity100
Maintenance100
Community48
Maturity36
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
81/100Excellent
Architecture85
Code Quality78
Innovation88
Learning Curve72

Takumi is a Rust-based rendering pipeline that converts JSX, HTML, and node trees directly into pixels, supporting output as PNG, animated GIF, or vector SVG. Instead of spinning up headless Chromium (roughly 300MB of RAM and a browser cold start per render), Takumi parses CSS, lays out the tree, shapes text, and composites layers inside a single native binary or WASM module, cutting rendering down to a function call.

The project ships as takumi-js for Node.js and WebAssembly runtimes, as a native Rust crate (takumi) for embedding in Rust applications, and provides a next/og-compatible ImageResponse API for drop-in replacement in Next.js OpenGraph image routes. CSS support extends well past typical OG-image subsets, covering Grid, pseudo-elements, masks, backdrop-filter, blend modes, and Tailwind v4 utilities.

What You Get

  • A render() function that converts JSX/HTML node trees into PNG, GIF, or SVG output
  • A next/og-compatible ImageResponse class for drop-in use in Next.js API routes
  • Prebuilt native binaries for macOS, Linux (glibc and musl), and Windows on x64/ARM64, plus a WASM build for edge/browser environments
  • Extensive CSS support: Grid, block/inline/float layout, ::before/::after, :is()/:where(), masks, clip-path, backdrop-filter, blend modes, conic gradients, RTL text, and Tailwind v4 utilities
  • Font loading helpers including Google Fonts integration and variable-font axis control
  • A reusable Renderer for batching many renders with fonts registered once

Common Use Cases

  • Generating OpenGraph/social preview card images dynamically at request time
  • Replacing a headless-Chromium image-generation pipeline (Puppeteer/Playwright) with a lighter-weight native renderer
  • Rendering animated GIFs or video keyframes from markup for messaging or content platforms
  • Producing SVG or PNG assets from JSX templates inside Cloudflare Workers or other edge runtimes

Under The Hood

Architecture: Takumi is structured as a Rust-first monorepo with the core rendering engine in takumi-core, layout/CSS handling split across takumi-html, takumi-svg, takumi-raster, and takumi-template, and multiple language bindings on top: takumi-napi (native Node.js bindings, published as @takumi-rs/core), takumi-wasm (WebAssembly bindings), and the top-level takumi-js package that bundles both native and WASM backends behind one API and auto-selects the backend per runtime (Workers/Deno/browser get WASM, Node/Bun get the native binding, per the imports.#backend conditional exports in package.json). takumi-helpers provides JSX/HTML-to-node-tree conversion, font loading, and emoji processing shared across bindings. Tech Stack: The rendering core is Rust (Cargo workspace, Cargo.toml/Cargo.lock at the root), cross-compiled to native binaries and to WASM via takumi-wasm; the JS-facing layer is TypeScript built with tsdown and tested with Bun; the project also maintains takumi-image-response as a deprecated shim that re-exports from takumi-js/response for backward compatibility. Code Quality: takumi-js includes a dedicated tests/bundlers.test.ts verifying compatibility across bundlers, alongside CI-oriented tooling (attw --pack, publint --strict) that checks published package correctness, renovate.json for automated dependency updates, and lefthook.yml for git hooks — signs of a maintained, tooling-conscious release process. API Design: The public API centers on a single render() function and a next/og-compatible ImageResponse class, letting Next.js users swap imports with no other code changes; font loading accepts URLs, raw bytes, or a googleFonts() helper, and the conditional exports map means consumers never manually pick a native vs. WASM backend.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search