Takumi

Comparison

takumi-pdf against Puppeteer and react-pdf, measured.

Three ways to render a PDF from JavaScript, benchmarked on a two-page, 80-line invoice with a page-number footer. Each harness writes the invoice in its engine's native template language with the same geometry (react-pdf's pt values mirror the px used by the other two), so this is an indicative end-to-end comparison, not a pixel-identical one. Warm figures are the median of 20 renders; the bench source reproduces the table with bun bench.

Environment: Apple M1 Pro, macOS 15.7, Bun 1.3.14, Chrome 150.

takumi-pdf 0.2@react-pdf/renderer 4.5.1Puppeteer + Chrome
Cold start to first PDF203 ms386 ms1.6–6.8 s
Warm render (median)30 ms127 ms218 ms
Output size11 KB5 KB102 KB
Deploy needs1.4 MB gzip wasmpure JSChrome install (hundreds of MB)
Template languageJSX, HTML, node trees with CSS and Tailwindits own primitives (<View>, <Text>, StyleSheet)HTML with full CSS
Selectable text, subset fontsyesyes (standard fonts not embedded)yes
Runs on edge runtimesyes (Cloudflare Workers)no (Node)no

Reading the numbers honestly:

  • Chrome's cold start covers launching a browser process; it varies with machine state, and its memory spreads across several processes that a single-process measurement misses. Once warm, Chrome is a capable renderer with the most complete CSS support of the three.
  • react-pdf's smaller output comes from the standard 14 PDF fonts, which viewers substitute rather than embed. Its cost is the template: documents are written in its own component set, so existing HTML/JSX and Tailwind markup cannot be reused.
  • takumi-pdf reuses OG-image components unchanged, but its CSS coverage is narrower than Chromium's: no box-shadow, filter, clip-path, or masks in PDF output yet.

Rule of thumb: pixel-perfect reproduction of an existing complex web page favors Puppeteer; documents written from scratch for PDF work in any of the three; reusing Takumi image components, deploying to edge runtimes, or cutting per-document latency favors takumi-pdf.

Last updated on