Comparison
takumi-pdf against Puppeteer and react-pdf, measured.
This comparison benchmarks three JavaScript PDF renderers. The benchmark uses an 80-line invoice. The invoice spans two pages and has a page-number footer.
Each harness uses its engine's native template language. Each harness uses the same geometry. react-pdf's pt values mirror the other renderers' px values. This is an indicative end-to-end comparison. It is not pixel-identical.
Warm figures are the median of 20 renders. The bench source reproduces this table. Run it 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.1 | Puppeteer + Chrome | |
|---|---|---|---|
| Cold start to first PDF | 203 ms | 386 ms | 1.6–6.8 s |
| Warm render (median) | 30 ms | 127 ms | 218 ms |
| Output size | 11 KB | 5 KB | 102 KB |
| Deploy needs | 1.4 MB gzip wasm | pure JS | Chrome install (hundreds of MB) |
| Template language | JSX, HTML, node trees with CSS and Tailwind | its own primitives (<View>, <Text>, StyleSheet) | HTML with full CSS |
| Selectable text, subset fonts | yes | yes (standard fonts not embedded) | yes |
| Runs on edge runtimes | yes (Cloudflare Workers) | no (Node) | no |
Bundle and install size
These measurements use npm-registry packages and esbuild (--bundle --minify, gzip). Install size comes from a clean bun add.
| JS bundle (min+gzip) | wasm (gzip) | node_modules | |
|---|---|---|---|
| takumi-pdf 0.1.4 | 10 KB | 1.66 MB (1.25 MB brotli) | 4.5 MB, 45 files |
| @react-pdf/renderer 4.5.1 | 493 KB | — | 32 MB, 1998 files |
| pdf-lib 1.17.1 | 179 KB | — | 26 MB |
| pdfkit 0.19.1 | 253 KB | — | 23 MB |
| jspdf 4.2.1 | 248 KB | — | 59 MB |
| Puppeteer + Chrome | — | — | Chrome install (hundreds of MB) |
pdf-lib, pdfkit, and jspdf are drawing primitives. You position each text line yourself. They are not in the benchmark above.
takumi-pdf's wasm binary is the largest single JS download. It is also the whole engine. node_modules has 45 files.
Reading the numbers honestly:
- Chrome's cold start includes launching a browser process. It varies with machine state. Its memory spans several processes. A single-process measurement misses this. Chrome performs well after warming. It has the most complete CSS support of the three.
- react-pdf's smaller output uses the standard 14 PDF fonts. Viewers substitute these fonts instead of embedding them. Documents use react-pdf's component set. Existing HTML, JSX, and Tailwind markup cannot be reused.
- takumi-pdf reuses OG-image components unchanged. Its CSS coverage is narrower than Chromium's. PDF output does not support
box-shadow,filter,clip-path, or masks yet.
Rule of thumb: use Puppeteer to reproduce a complex web page pixel-perfectly. Any renderer suits documents written from scratch for PDF work. Use takumi-pdf to reuse Takumi image components. It suits edge runtimes. It also offers lower per-document latency.
Last updated on