§ Puppeteer alternative
Puppeteer Alternative: Managed Headless Chrome PDF Rendering, No Fleet
Puppeteer is an excellent library and a miserable service to operate. If you are here because the browser fleet keeps waking someone up, this page is the honest version of the trade off, including when you should just keep Puppeteer.
- Early access, launching soon
- No card required
- Your HTML stays yours
§ Short answer
The best Puppeteer alternative for PDF generation is a managed rendering API: you keep the same Chromium output quality, but the vendor runs the browser pool, patches it, and absorbs the memory leaks. Puppeteer itself is free; what costs money is the engineer who owns the fleet. Swap the library for one HTTP call when render reliability starts consuming on call time, or when you need a dated record of what you rendered, which no headless browser gives you.
Last updated July 2026. Written and fact checked by the Sitepdf team.
§ 00
Puppeteer, wkhtmltopdf and a managed API, side by side
This is a comparison of operating models, not a benchmark. All three produce good PDFs on a good day. They diverge on who fixes it at 3am.
| Puppeteer (self-hosted) | wkhtmltopdf | Sitepdf API | |
|---|---|---|---|
| Licence cost | Free (Apache 2.0) | Free (LGPL) | Paid, from $29/mo planned |
| Rendering engine | Current Chromium | Old WebKit fork, archived upstream | Managed current Chromium |
| Modern CSS and JS | Full support | Partial: flexbox and grid are unreliable | Full support |
| Who runs the browser | You do | You do | We do |
| Typical failure mode | Memory leak, zombie processes, pool wedges | Silently renders the page wrong | Explicit error, no quota charged |
| Wait for late content | You write it yourself | Not really | wait_for selector, built in |
| Timestamped archive of the render | No | No | Yes, archive=true |
| Scales by | Adding servers you manage | Adding servers you manage | Your plan's concurrency |
Licence and engine facts are from each project's own documentation. wkhtmltopdf's upstream repository has been archived and its maintainers recommend moving to a Chromium based renderer, which is the honest reason it sits third here.
§ 01
The bill for "free" is not zero, it is just not on the invoice
Puppeteer costs nothing to install. It costs a great deal to run. The pattern is so consistent it is almost a rite of passage: a single puppeteer.launch() in a request handler works beautifully in staging, then production traffic arrives and the box runs out of memory because browsers were never closed on the error path. So you build a pool. The pool wedges. So you add a health check and a reaper. Chrome ships a new major version and your page breaks in a way that reproduces on nobody's laptop. Someone patches a font package at 11pm because Arabic invoices are rendering as boxes.
None of that appears on a budget line. It appears as an engineer's week, repeatedly, and as the on call rotation nobody volunteers for. The library is free; the fleet is a product you did not mean to build and do not get paid for.
We wrote the full arithmetic in HTML to PDF library vs API, including the volumes at which self-hosting genuinely does win.
§ 02
When you should keep Puppeteer, honestly
We are not going to pretend the API is always right. Keep the library when any of these are true. Your rendering needs are trivial and stable, a handful of simple templates that have not changed in a year. You already operate browser automation for other reasons, scraping or end to end tests, so the fleet exists whether or not you make PDFs with it. Your data cannot leave your network for regulatory reasons, and no vendor contract fixes that. Or your volume is so high that per render pricing genuinely exceeds the cost of servers plus the fraction of an engineer who tends them.
That last one is a real number, not a rhetorical one. Work it out before you buy anything. If self-hosting wins on your numbers, self-host.
§ 03
What you get by switching that Puppeteer cannot give you at all
Output quality is a wash. It is the same engine, so the PDF looks the same. What changes is everything around the render.
The pool, the patching and the page at 3am become someone else's job. Failed renders return an explicit error with the HTTP status the page returned, instead of a blank PDF you discover three weeks later in a customer complaint. And the render can carry a record: archive=true stores a timestamped, immutable snapshot of the page under your account, retrievable by id for the life of your retention window. Headless Chrome has no concept of this, and bolting it on means building a second pipeline, a storage layer and a retention policy. Archiving is the half of the job Puppeteer was never going to do for you.
If a record is the reason you are reading this, the save webpage as PDF and screenshot API pages cover the capture side, and the PDF generator API covers document generation from your own templates.
§ 04
Migrating off the fleet is a one function change
Almost every Puppeteer PDF integration reduces to one internal function: give it HTML or a URL, get back a buffer. Replacing the body of that function with an HTTP call is usually an afternoon, and you can run both paths side by side behind a flag while you compare output on real documents. Nothing about your templates changes, because the engine did not change.
Planned tiers are on the pricing page, and the seven tool comparison lists the other vendors worth pricing against us, because you should check.
// before: you own the browser, the pool and the leak
const browser = await puppeteer.launch({ args: ['--no-sandbox'] })
const page = await browser.newPage()
await page.goto(url, { waitUntil: 'networkidle0' })
await page.waitForSelector('.order-summary')
const pdf = await page.pdf({ format: 'A4' })
await browser.close() // the line everyone forgets on the error path
// after: one call, plus a dated record you never had before
const res = await fetch('https://api.sitepdf.com/v1/render', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.SITEPDF_KEY}` },
body: new URLSearchParams({
url,
wait_for: '.order-summary',
format: 'A4',
archive: 'true',
}),
})
const { pdf_url, archive } = await res.json()
The API is in early access; this is the documented call shape it opens with. Full request and response walkthrough.
§ 05
Questions about this job
What is the best alternative to Puppeteer for generating PDFs?
Why does Puppeteer leak memory in production?
Is wkhtmltopdf still a good option in 2026?
Will my PDFs look different if I switch from Puppeteer to an API?
How hard is it to migrate off Puppeteer?
§ Index
More PDF and archiving tools
- Convert HTML to PDF
- Webpage to PDF
- Save webpage as PDF
- URL to PDF API
- Website archiving
- Screenshot API
- React to PDF
- Laravel HTML to PDF
- Vue to PDF
- Next.js PDF generator
- Angular to PDF
- Markdown to PDF API
- Django HTML to PDF
- Blazor HTML to PDF
- Spring Boot HTML to PDF
- Airtable to PDF
- Rails HTML to PDF
- PDF generator API
- Document generation API
- Bulk HTML to PDF
- Wayback Machine alternative
- Best HTML to PDF API
- DocRaptor alternative
- Wkhtmltopdf alternative
- PDFShift alternative
- Urlbox alternative
- PDFCrowd alternative
- Api2Pdf alternative
- Browserless alternative
- APITemplate alternative
- CraftMyPDF alternative
- PDFMonkey alternative
- dompdf alternative
- Gotenberg alternative
- GrabzIt alternative
- How it works
- Features
- Pricing
§ Early access
Get on the early-access list
The API opens to the list first, in order. Early access locks the planned launch rates for 12 months. No card required, launching soon.