Puppeteer alternative for HTML to PDF

Puppeteer alternative for HTML to PDF

Puppeteer alternative for PDFs: compare Playwright, Gotenberg and hosted APIs, and map page.pdf() options to a simple JSON PDF API.

Quick answer. If you only run Puppeteer to make PDFs, send your HTML to a hosted Chromium API instead. You get the same print engine as page.pdf() without running a browser.

curl -X POST https://html-pdf.com/v1/pdf \
  -H "Authorization: Bearer $HTML_PDF_KEY" \
  -H "Content-Type: application/json" \
  -d '{"html": "<h1>Hello</h1>", "format": "A4"}' \
  -o out.pdf

Puppeteer is a great library. page.pdf() gives you Chrome's own print engine from Node.js, and a prototype takes about ten lines of code. The trouble starts when PDF generation becomes a production service that has to stay up.

This page explains why teams stop self-hosting Puppeteer for PDFs, what the realistic options are, and how to move existing page.pdf() calls to an API.

Why teams move away from self-hosted Puppeteer

Here are the problems that usually push teams to look elsewhere. None of them are bugs in Puppeteer. They come from running a full browser inside your app.

The options

This table compares the four realistic ways to produce Chromium-quality PDFs.

Puppeteer (self-hosted) Playwright (self-hosted) Gotenberg (self-hosted) Managed PDF API (html-pdf.com)
What it is Node.js library driving Chrome Library for Node.js, Python, Java, .NET Docker image with an HTTP API around Chromium and LibreOffice Hosted HTTP API
PDF engine Chromium Chromium (PDF is Chromium-only) Chromium Headless Chromium via Gotenberg
You run a browser Yes Yes Yes, inside one container No
Languages JavaScript/TypeScript Several Any (HTTP) Any (HTTP) or MCP
Cost Your servers Your servers Your servers (MIT licensed) Per page, credits never expire
Best for Full control in Node.js Teams already using Playwright Self-hosting without writing browser code Not running PDF infrastructure

Playwright has the same page.pdf() model and the same operational problems. It does have a nicer API and support for more languages. See Playwright HTML to PDF.

Gotenberg moves the browser into a dedicated container you call over HTTP. That solves process management and language lock-in, but you still host, scale and patch it. See self-host Gotenberg with Docker.

A managed API removes the browser from your stack entirely.

When Puppeteer is still the better choice

Puppeteer still wins in a few cases. Keep it if any of these apply.

Or skip the server

This section shows how a page.pdf() call looks after moving to html-pdf.com. We run Chromium for you. You send HTML or a public URL and get a PDF back, with the same print engine as page.pdf().

// Before: Puppeteer
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setContent(html, { waitUntil: "networkidle0" });
const pdf = await page.pdf({
  format: "A4",
  printBackground: true,
  margin: { top: "20mm", right: "15mm", bottom: "20mm", left: "15mm" },
  displayHeaderFooter: true,
  headerTemplate: "<span></span>",
  footerTemplate: '<div style="font-size:9px;width:100%;text-align:center">Page <span class="pageNumber"></span> of <span class="totalPages"></span></div>',
});
await browser.close();
// After: html-pdf.com (Node.js 18+, no browser)
import fs from "node:fs/promises";

const res = await fetch("https://html-pdf.com/v1/pdf", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.HTML_PDF_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    html,
    format: "A4",
    print_background: true,
    margin: { top: "20mm", right: "15mm", bottom: "20mm", left: "15mm" },
    footer_html: '<div style="font-size:9px;width:100%;text-align:center">Page <span class="pageNumber"></span> of <span class="totalPages"></span></div>',
  }),
});
if (!res.ok) throw new Error(await res.text());
await fs.writeFile("out.pdf", Buffer.from(await res.arrayBuffer()));

page.pdf() options to JSON options

Puppeteer html-pdf.com
page.setContent(html) "html": "..."
page.goto(url) "url": "https://..." (public pages only)
format: "A4" "format": "A4" (A3 to A6, Letter, Legal, Tabloid)
width / height "width" / "height", e.g. "210mm"
landscape: true "landscape": true
margin: {top, right, bottom, left} "margin": "10mm" or {top, right, bottom, left}
printBackground: true "print_background" (defaults to true)
preferCSSPageSize: true "prefer_css_page_size": true
scale "scale" (0.1 to 2)
pageRanges: "1-3" "page_ranges": "1-3"
displayHeaderFooter + headerTemplate / footerTemplate "header_html" / "footer_html" (classes pageNumber, totalPages, date, title; leave room with margin)
page.emulateMediaType("screen") "media": "screen"
page.waitForFunction("window.ready") "wait_for_expression": "window.ready === true"
waitForTimeout(2000) "wait_delay": 2 (0 to 10 seconds)
path: "out.pdf" "filename": "out.pdf", or "response": "url" for a 24-hour link

Puppeteer can load local images and fonts from disk, but an API can't. Use absolute https:// URLs, inline data URIs, or a multipart request with index.html plus asset files and an options JSON field.

Add "max_pages": 20 to fail runaway documents without being charged.

For AI agents, the remote MCP server at https://html-pdf.com/mcp exposes html_to_pdf and url_to_pdf. Claude, ChatGPT or Cursor can then create PDFs without any code.

Pricing

Here is what it costs. 1 credit = 1 PDF page. You get 100 free credits once you confirm your email, then packs from $10 for 1,000 pages down to $250 for 50,000 ($0.005 per page).

Purchased credits never expire, auto top-up is optional, and failed renders are free. Limits are 20 MB per request, 30 s per render and 120 requests per minute.

curl -X POST https://html-pdf.com/v1/signup -H "Content-Type: application/json" -d '{"email": "you@example.com"}'
# Then open the link we email you to confirm (adds the 100 free credits)

Get a free API key · API docs · Puppeteer HTML to PDF guide · HTML to PDF in Node.js

FAQ

What is the best alternative to Puppeteer for generating PDFs?

If you want to keep running the browser yourself, Playwright or Gotenberg are the closest options. If you don't want to run any PDF infrastructure, a hosted Chromium API like html-pdf.com gives the same output from one HTTP call.

Does html-pdf.com produce the same PDFs as Puppeteer page.pdf()?

Yes, it renders with headless Chromium, the same print engine behind page.pdf(). Most options map one to one, for example printBackground becomes print_background and footerTemplate becomes footer_html.

Can I convert a page behind a login without Puppeteer?

The API only reaches public URLs. For private pages, render the HTML on your own server and send it in the html field instead of url.

How much does a Puppeteer alternative API cost?

html-pdf.com charges 1 credit per PDF page, with 100 free credits once and no card required. Packs range from $10 for 1,000 pages to $250 for 50,000, purchased credits never expire, and failed renders cost nothing.

This page as markdown · text