Skip to content
TryDocify

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 provideHTML and CSS templatesA JSON document
Runs on your serversChromium, fonts, system librariesNothing; one HTTPS call
Page breaks, repeated headersCSS and print options, tuned by handAutomatic
Page numbersHeader/footer templatesshowPageNumbers
Design freedomAnything CSS can doTen composable blocks and a theme
Remote resources while renderingLoaded unless blockedNever fetched
Best forPixel-perfect and free-form designsInvoices, 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:

bash · terminal
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.pdf

Then 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.