html4pdf vs Puppeteer
This is not really a comparison of two renderers. Both are headless Chrome, so the output is the same. What differs is who runs the browser.
The short answer
Run Puppeteer yourself if PDFs are high volume and you already operate containers. Use an API if PDFs are a feature of your product and you do not want Chrome in your deployment.
What Puppeteer is
Puppeteer is a Node library that drives Chrome or Chromium over the DevTools protocol. You launch a browser, open a page, set its content, and call page.pdf(). It is free, it is maintained by the Chrome team, and because the renderer is Chrome, whatever you see in your browser is what you get in the document.
Side by side
| Puppeteer | html4pdf | |
|---|---|---|
| Rendering engine | Headless Chrome | Headless Chrome |
| CSS and JavaScript | Everything Chrome supports | Everything Chrome supports |
| What you deploy | Your app plus a Chromium binary, a few hundred megabytes | Nothing. One HTTPS call |
| Serverless | Possible with a stripped Chromium build, close to size limits, slow cold starts | Works anywhere a fetch works |
| Memory | A browser process per render, which you size and cap yourself | Not your problem |
| Cost per document | Whatever your own compute costs | From $0.033, one credit |
| Ongoing work | Chrome updates, zombie processes, concurrency limits | None |
| Data | Stays inside your infrastructure | Rendered in memory, never stored |
| Languages | Node, or a port such as Pyppeteer or PuppeteerSharp | Any language with HTTP |
Choose Puppeteer when
- You render thousands of documents a day and the per-document cost matters more than the operational cost.
- You already run containers and have somewhere sensible to put a browser.
- You need more than a PDF: screenshots, scraping, interacting with the page before printing.
- Your documents must never leave your own infrastructure, even in memory.
Choose html4pdf when
- PDFs are a feature, not your product, and you do not want to operate a browser for them.
- You deploy to Lambda, Vercel, Cloud Run or anywhere a 300MB dependency hurts.
- You are not writing Node, and the ports are a worse fit than an HTTP call.
- You want the first version shipped this afternoon.
What the change looks like
The shape of the change: everything from launch to close becomes one request, and the PDF buffer arrives the same way.
import puppeteer from "puppeteer"
const browser = await puppeteer.launch({ args: ["--no-sandbox"] })
const page = await browser.newPage()
await page.setContent(html, { waitUntil: "networkidle0" })
const pdf = await page.pdf({ format: "A4", printBackground: true })
await browser.close()const res = await fetch("https://api.html4pdf.com/generate-pdf", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.HTML4PDF_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
html,
responseFormat: "binary",
options: { format: "A4", printBackground: true },
}),
})
const pdf = Buffer.from(await res.arrayBuffer())See the code
The working example, in the language this decision is being made in.
Puppeteer: common questions
Is html4pdf just Puppeteer as a service?
Effectively, yes, and we would rather say so than pretend otherwise. The renderer is headless Chrome. What you are buying is not a better engine, it is not having to run one.
Will my PDFs look different if I switch?
They should not. Same engine, same CSS support, same page options. Fonts and stylesheets need absolute URLs either way.
Why is Puppeteer hard in serverless?
A full Chromium does not fit inside most function size limits, so you need a stripped build such as @sparticuz/chromium, and the first request after a cold start pays several seconds to boot the browser.
Which is cheaper?
At high volume, your own Puppeteer, by a lot. At low and spiky volume, an API, once you count the instance that has to stay warm and the hours spent on memory leaks.
Can I use both?
Plenty of teams do: the API while the feature is small, their own renderer once volume justifies it. Because the body is plain JSON, swapping back is a contained change.
Try it before you decide
New accounts get 10 free credits, no card. Send the HTML you already have and compare the output against whatever you are using now.
Other comparisons
- html4pdf vs wkhtmltopdfwkhtmltopdf is still fine for simple documents you already have working. For anything new, or anything using modern CSS, its archived WebKit engine is the problem you will eventually hit.
- html4pdf vs WeasyPrintIf your document is HTML and CSS with no scripts, WeasyPrint is excellent and free, and you should use it. If anything on the page is drawn by JavaScript, you need a browser.
- html4pdf vs DompdfDompdf is the right answer for a simple document on shared hosting with no extra services. It is the wrong answer for anything designed with modern CSS, because it implements CSS 2.1.
- html4pdf vs jsPDF and html2canvasjsPDF with html2canvas is free and needs no backend, and it produces a picture of your page rather than a document. If the text has to be selectable, searchable or printable at quality, it is the wrong tool.
- html4pdf vs @react-pdf/rendererUse react-pdf when the document is small, stable, and worth building as its own component tree. Use a renderer when the PDF should be the same thing your users already see on screen.
- html4pdf vs printing from the browserIf the user is the one who wants the PDF and is sitting in front of the page, use window.print() and a print stylesheet. If your system needs the file, you need a renderer.
- html4pdf vs PlaywrightPlaywright is the better browser automation library. It is not a better PDF pipeline, because the cost was never the library: it is operating the browser. Use it if you already run it, call an API if you do not.
- html4pdf vs running Chromium in a LambdaIt works, it is free, and it is the single most fiddly part of most codebases that do it. If your function is already near the size limit or your users wait on the first request, the trade has stopped paying.
- html4pdf vs GotenbergGotenberg is the right answer if you want this capability inside your own infrastructure and have somewhere to run a container. We are the right answer if you want it without running anything.
- html4pdf vs mPDFmPDF is the best free answer in PHP for long, table-heavy documents written as documents. It is still its own engine, so a design built in a browser will not arrive intact.
- html4pdf vs ReportLabReportLab is the right tool when the document is a fixed, precise artefact and you want no dependencies. It is the wrong tool when the design changes often, because every change is a code change.
- html4pdf vs iTextIf you need deep PDF manipulation on the JVM and can accept AGPL or buy a licence, iText is the strongest tool available. If you only need HTML turned into a document, the licence question is one you can skip entirely.
- html4pdf vs QuestPDFQuestPDF is excellent for documents you are happy to describe in C#. If the document already exists as a web page, you would be rebuilding it, and that duplication is the whole cost.
- html4pdf vs PDFKitPDFKit is a good fit for simple, fixed documents generated at volume, where no browser and no network is worth writing the layout by hand. Beyond that the hand-written layout becomes the problem.