Better PDFby Evenpine
Better PDF blog

Generating PDFs from JSON: why it is still painful in 2026

· 6 min read · developers, pdf-generation, templates, research

In short: In 2026 most PDFs made from data go through one of three routes: an HTML-to-PDF service priced per document, a headless browser you run yourself, or a library you program page by page. Each one works, and each has the same weak spots: tables that break badly across pages, missing glyphs, blank form fields, untagged output, and signing that needs another tool afterwards.

Every business sends the same documents again and again: invoices, receipts, certificates, payslips, contracts with a name and a date changed. The data is already in a database or a spreadsheet as JSON or CSV. Turning it into a good PDF should be a solved problem. In 2026 it mostly is not, and the people who do it every day say so.

We are building a tool in this space, which we describe in What we are building next, so read this with that in mind. This post is the research we did first: what people use and what goes wrong, with the sources at the end. We checked prices on 9 November 2026.

The three routes people take

A hosted template service. You design a template in a web editor or in HTML, send JSON to an API and get a PDF back. DocRaptor, PDFMonkey, Documint, Anvil, PDF Generator API, APITemplate.io and Carbone all work this way. Small volumes are free or cheap: DocRaptor gives 5 documents a month free and charges $149 for 5,000, PDFMonkey €60 for 5,000, and Anvil $0.10 a generation after its free credits. It is the quickest start there is.

A headless browser. You write HTML and CSS, then have Chromium print it, through Puppeteer, Playwright or a container such as Gotenberg. It is free and uses skills a web team already has. The old alternative, wkhtmltopdf, has been archived since January 2023, so most of its users have moved here.

A library. You draw the document in code: pdf-lib in JavaScript, ReportLab or WeasyPrint in Python, Prawn in Ruby, iText in Java and .NET, or a typesetting system such as LaTeX or Typst fed with data. On Apple platforms you draw with Core Graphics or render a SwiftUI view. It gives the most control and asks the most work.

Where it goes wrong

These are the problems that came up most often in forum threads, issue trackers and engineering write-ups, roughly in order of how often we saw them.

1. Page breaks and tables. In HTML, break-inside: avoid is a hint, and browsers have long ignored it inside flex and grid layouts. Rows split across pages, totals land alone on a new page, and header rows repeat only if the table uses a real header group. An Ask HN thread from October 2025 lists page breaks behaving differently from browser to browser as a main reason people are still looking.

2. A browser on a server. Chromium is large and hungry. On AWS Lambda the usual Chromium build is about 67 MB compressed and over 200 MB unpacked, and functions need 1 to 2 GB of memory. Cold starts are slow, and Gotenberg’s tracker has reports of memory growing until the container is killed. Zerodha, the Indian broker, wrote up how it moved its contract notes off headless Chrome, which had become slow and resource-hungry as volume grew, to reach 1.5 million PDFs in 25 minutes.

3. Fonts and missing glyphs. A container that renders Chinese text correctly on a laptop shows empty boxes once deployed, because the slim image has no CJK fonts. Libraries that start with the 14 standard PDF fonts fail on the first character outside Western European, with errors like “WinAnsi cannot encode”. Emoji, Indic scripts and Arabic need fonts embedded on purpose, and right-to-left text needs shaping that some libraries added only recently. ReportLab’s HarfBuzz support arrived as experimental in version 4.4.

4. Filling existing forms. Many documents start as an AcroForm from a government or a bank. Filling one from JSON sounds easy, but fields often come out blank in some viewers until the library regenerates their appearance or sets a flag that asks the viewer to do it. Checkboxes behave differently from viewer to viewer, and non-ASCII text can break when the form is flattened.

5. Headers, footers and page numbers. Chromium renders header and footer templates in an isolated context. They cannot see the page’s CSS or run scripts, images must be inlined, and margins have to be reserved by hand. “Page 3 of 7” is a configuration puzzle, not a variable.

6. Price per document. Every hosted service prices by document or by credit. That is fair at 100 a month. At 50,000 a month it is a line in the budget, and running it yourself moves the cost to servers and someone’s time.

7. Accessibility. Tagged PDF, which screen readers need and PDF/UA requires, is still uneven. Chromium’s tagged output has been experimental. WeasyPrint says its PDF/UA and PDF/A output is not guaranteed to be valid. Typst is the bright spot: version 0.14, in October 2025, tags documents by default and can target PDF/UA-1.

8. Signing afterwards. Almost no generator signs. Zerodha found no library that would batch-sign its PDFs and built a separate signing service. In Node, the best-known signing package was deprecated for a successor. Signing is nearly always a second tool, a second step and a second place for things to fail.

9. Archiving and e-invoicing. PDF/A for long-term archiving, and European e-invoices such as ZUGFeRD and Factur-X, need a PDF/A-3 file with an embedded XML invoice and a colour profile. The libraries for it are scattered across languages, and several describe themselves as a work in progress.

10. Licences and lock-in. iText is AGPL, so using it in a closed product or a SaaS needs a commercial licence, and that licence has no public price. Carbone’s core is source-available rather than open source. A template built in one vendor’s web editor rarely moves to another, and it is hard to keep in version control next to the code it serves.

Further down the list: layout errors that are hard to debug (Zerodha’s write-up describes LaTeX running out of memory and breaking on large tables), the handoff between the person who designs the document and the person who wires up the data, and on Apple platforms, a SwiftUI view rendered to PDF that gets cut off once it is taller than a page.

What has got better

It is not all bad news. Typst has made data-driven typesetting fast and its errors readable, and Zerodha reports a 2,000-page document compiling in about a minute instead of 18. Gotenberg packages Chromium and LibreOffice into one maintained container. The hosted services have good editors, and for a small team the per-document price is often the cheapest option there is. If one of them works for you, keep it.

What we take from it

The same few problems keep coming back whatever the route: pagination, fonts, forms, tags, signing. They are document problems, not web problems, and a browser engine is a heavy way to solve them. That is the reason we are building a designer and an engine that run on the device, without a browser. The next post says what it is: What we are building next: Better PDF Designer and the SDK.

If you generate PDFs from data and something here is missing or wrong, write to [email protected]. We would like to hear it.


Sources, checked on 9 November 2026. Pricing: https://docraptor.com/signup, https://pdfmonkey.io/pricing, https://documint.me/pricing, https://www.useanvil.com/pricing, https://pdfgeneratorapi.com/pricing, https://apitemplate.io/pricing/, https://carbone.io/pricing.html. Tools: https://github.com/wkhtmltopdf/wkhtmltopdf (archived), https://github.com/gotenberg/gotenberg, https://github.com/Hopding/pdf-lib, https://playwright.dev/docs/api/class-page#page-pdf, https://typst.app/docs/reference/foundations/sys/, https://itextpdf.com/how-buy. Accounts and threads: https://zerodha.tech/blog/1-5-million-pdfs-in-25-minutes/, https://news.ycombinator.com/item?id=45404760, https://www.useanvil.com/ask-anvil/pdfs/html-to-pdf-page-breaks-wrong-place/, https://apitemplate.io/blog/html-to-pdf-aws-lambda-serverless-guide/, https://repost.aws/questions/QU2LoyQ023REmihjDCGWi-dA, https://github.com/pdfme/pdfme/issues/472, https://bugs.launchpad.net/ubuntu/+source/pdftk/+bug/663603, https://github.com/puppeteer/puppeteer/issues/12360, https://typst.app/blog/2025/accessible-pdf, https://github.com/vbuch/node-signpdf, https://docs.reportlab.com/releases/notes/whats-new-44/, https://developer.apple.com/forums/thread/730876.

Questions people ask

What is the easiest way to turn JSON into a PDF?
For a few documents a month, a hosted template service is the easiest: you design a template, send JSON and get a PDF back, usually free for small volumes. At higher volumes the per-document price adds up, and the template lives in that vendor's format.
Why do tables break badly in HTML-to-PDF output?
Browsers treat CSS page-break rules as hints. Rows can be split across pages, and header rows repeat only when the table is marked up with a real header group. Layouts built with flex or grid have been especially unreliable.
Can I sign a PDF while generating it?
Rarely in the same tool. Most generators produce an unsigned file, and signing is a second step with a separate library or service. Some teams build a small signing service just for this.