Takumi

How Takumi works

Learn how Takumi turns JSX, HTML, and CSS into images, PDFs, or paint trees, and where it behaves differently from a browser.

Takumi is one Rust engine. Its text and inline layout port Chromium's Blink, and the same layout feeds three packages.

  • boxdiv
  • boxdiv
  • boxdiv
  • boxb
  • text"Hello, paint"
  • boxspan
  • text"Boxes, text, and steps"
A render starts from JSX, an HTML string, or a node tree of container, text, and image nodes.

From input to output

Input

A render starts with JSX, an HTML string, or a node tree. Every node in a tree is a container, text, or image. A node tree holds content and style only, so fonts, images, and output options are separate arguments to render. Parsing templates covers the input forms.

Styles

Styles come from the style prop, a stylesheet, or Tailwind utilities. A stylesheet reaches Takumi through css or a <style> tag, and the tw prop runs a built-in Tailwind parser that needs no build step. The style prop beats the tag default and every matching stylesheet rule of the same importance. Styles says which declaration wins.

Layout and output

Layout covers Flexbox, Grid, block, float, tables, and inline layout from Blink. The same layout produces every output:

PackageOutput
takumi-jsPNG, JPEG, WebP, ICO, raw pixels, SVG, and animated WebP, APNG, or GIF
takumi-pdfPaged PDF with selectable text
takumi-paintA paint tree to draw with Canvas, slides, or a native API

Where it differs from a browser

Fonts

Takumi never reads system fonts, and its one built-in font is Geist, which covers Latin at weights 300 to 800. Load a font for every script your text uses. See Fonts.

One static frame

Interactive pseudo-classes such as :hover and :focus parse but never match. In @media, image renders are screen and PDF renders are print. Any feature the media query table does not list matches nothing, prefers-color-scheme included. See Styles.

Tailwind and rem

The built-in parser applies no Tailwind Preflight by default, so elements keep their default margins. In a tree without an <html> root, rem resolves against the viewport's font size, which is 16px. A full HTML document passed to fromHtml keeps its <html> element, so a font size there sets the rem basis. See Styles and the reference.

Strict style objects

A property name outside the supported list is dropped without an error. A listed name with an unparsable value fails the whole style object. Only writing-mode: horizontal-tb is laid out. See the reference.

Tables

Tables follow Chromium's table layout, with a few cases that drift, such as how a row baseline is measured and where page breaks fall. See Tables.

Remote images

Remote images load only from an <img> src and from background-image, mask-image, and list-style-image in a node's style or tw. Takumi does not fetch URLs inside css or a <style> tag, so pass those images as pre-fetched images. See Image loading & emoji.

PDF filters

A PDF cannot draw filter: blur() or drop-shadow(). The renderer stops rather than ship a page that differs from the image output. See Troubleshooting.

Coming from satori

The migration guide lists the differences between satori or next/og and Takumi.

Last updated on