Comparison
PDF generation without Puppeteer: HTML to PDF vs JSON to PDF
When a headless browser is the right tool for PDFs, when it isn't, and how JSON to PDF compares on pagination, deployment, speed and maintenance.
Updated · Every code sample on this page is run against the API before publishing.
Two ways to make a PDF
HTML to PDF renders a web page in a browser engine and prints it. In practice that means Puppeteer or Playwright driving headless Chromium, or a service that runs Chromium for you. You design the document with HTML and CSS.
JSON to PDF describes the document as data (headings, tables, totals, notes) and lets a dedicated layout engine typeset it. There is no page to design and no browser: you send structure, and the engine decides line breaks, page breaks and repeated headers.
Neither is better in general. They suit different documents, and the right choice depends on what you are printing.
What a headless browser costs
Deployment
Puppeteer downloads a full Chromium build, which is hundreds of megabytes, and Chromium needs a set of system libraries and fonts on Linux. Container images grow, serverless functions approach their size limits, and a missing font silently changes your layout in production.
Memory, cold starts and concurrency
Each browser process uses a significant amount of memory, and starting one takes noticeable time. To render many PDFs you end up pooling browsers or pages, restarting them when they leak or crash, and limiting concurrency so a burst of requests doesn't exhaust the server.
Pagination
Browsers are built for scrolling, not pages. You can get good results with CSS such as break-inside: avoid and repeated thead rows, but page numbers and running headers have to go through the PDF options' header and footer templates, and getting a long table to break cleanly usually takes trial and error.
Security
A browser rendering HTML that contains user data will happily load remote images, fonts and scripts. Unless you lock it down, a crafted value can make your server request internal URLs (server-side request forgery) or run scripts during rendering.
Maintenance
Chromium updates frequently. Upgrades can shift layout or change PDF output, so the pipeline needs visual regression checks and patching like any other browser on your servers.
When HTML to PDF is the right call
- You already have pixel-perfect HTML templates and want the PDF to match the web page exactly.
- The design is free-form: magazine-style layouts, complex positioning, custom CSS everywhere.
- The content is rendered by JavaScript, such as charts drawn in the browser.
- You need to capture an existing web page as it appears on screen.
For these, a headless browser is the honest answer, and a JSON format would get in the way.
When JSON to PDF fits better
Most business documents are data with a predictable shape: invoices, receipts, statements, reports, packing slips, certificates. For these, the structure is already in your database, and what you need is reliable pagination rather than design freedom.
- There is nothing to install or run: it is one HTTPS request from any language.
- Tables flow across pages with the header repeated, and page numbers are built in.
- Rendering is fast because there is no browser to start. In our benchmarks a one-page invoice renders in about 12 ms.
- Nothing is fetched from the network while rendering: images are sent inline as base64, so there is no SSRF risk.
- Text stays selectable and searchable, and files stay small.
Side by side
| HTML to PDF (headless browser) | JSON to PDF (TryDocify) | |
|---|---|---|
| You provide | HTML and CSS templates | A JSON document |
| Runs on your servers | Chromium, fonts, system libraries | Nothing; one HTTPS call |
| Page breaks, repeated headers | CSS and print options, tuned by hand | Automatic |
| Page numbers | Header/footer templates | showPageNumbers |
| Design freedom | Anything CSS can do | Ten composable blocks and a theme |
| Remote resources while rendering | Loaded unless blocked | Never fetched |
| Best for | Pixel-perfect and free-form designs | Invoices, receipts, reports, statements |
Moving a template over
Take an existing HTML invoice or report and map each section to a block: the heading area to title and subtitle, label/value grids to keyValue, the line items to a table with totals in its footer, and callouts to note. The template logic you had in Handlebars, EJS or Razor becomes the code that builds the JSON, which you can unit test without rendering anything.
Try the smallest possible document to see the output:
curl -X POST https://api.trydocify.com/api/v1/generate \
-H "X-API-Key: $TRYDOCIFY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"test": true,
"title": "Hello, PDF",
"blocks": [
{ "type": "paragraph", "text": "This PDF was generated from JSON." }
]
}' \
--output hello.pdfThen follow the step-by-step JSON to PDF tutorial or the invoice example.
Try it with your own data
Every plan includes 200 free test renders a day. Add "test": true while you build, and remove it when you go live.