Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use Playwright or Puppeteer when the page behaves like an application; use WeasyPrint, Paged.js, Vivliostyle CLI, or OpenHTMLtoPDF when it is a print-first document. Browser engines execute JavaScript and match modern CSS, while paged-media engines give you more deterministic pagination without shipping Chromium. Managed services such as Browserless or Doppio are sensible when maintaining browsers, scaling workers, and patching security issues is not part of your team’s operating model. Treat wkhtmltopdf as a migration target for new systems.

Choose by the document you actually have

HTML-to-PDF is not one problem. A server-rendered invoice, a React dashboard with charts, and a long compliance report need different rendering engines. Start with these questions:

  • Does the page need client-side JavaScript, canvas charts, a single-page-app route, or data fetched after navigation?
  • Do print rules, page breaks, running headers, footnotes, and repeatable pagination matter more than browser pixel fidelity?
  • Can your deployment carry a Chromium binary and its memory, patching, and startup cost?
  • Do you need a library inside your process, or an HTTP API with retries, queues, and operational support?
Primary requirement Best starting point Why
JavaScript dashboards, SPAs, charts, web fonts, modern CSS Playwright or Puppeteer They drive a real browser and execute the page before printing.
Node service with a small abstraction layer Puppeteer page.pdf() provides a direct browser-to-PDF path.
Polyglot team that wants browser fidelity Playwright or a managed Browserless-style API Playwright offers bindings beyond Node; a service removes browser operations from application hosts.
Print-heavy, controlled templates with little JavaScript WeasyPrint, Paged.js, Vivliostyle CLI, or OpenHTMLtoPDF These are designed around paged media and predictable layout.
No browser operations team, bursty traffic, or high volume Managed API such as Browserless or Doppio The provider handles browser workers and exposes HTTP or asynchronous workflows; verify residency, quotas, SLA, and price first.
Existing wkhtmltopdf deployment Plan a controlled migration Current comparison sources describe it as archived or unmaintained, with no modern JavaScript/CSS support.

Browser-based conversion: Playwright and Puppeteer

Why a real browser wins for dynamic pages

Headless Chromium evaluates scripts, lays out flexbox and grid, loads web fonts, paints canvas and SVG charts, and follows the same print pipeline users receive in a browser. That makes it the practical choice for SPAs and dashboards. The trade-off is operational: Chromium is a large dependency, consumes memory per worker, and must be patched and isolated like any other browser.

Playwright example (Node.js)

Install the library and its browser once in your build or image:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
MixPad Free Multitrack Recording Studio and Music Mixing Software [Download]
  • Create a mix using audio, music and voice tracks and recordings.
  • Customize your tracks with amazing effects and helpful editing tools.
  • Use tools like the Beat Maker and Midi Creator.
  • Work efficiently by using Bookmarks and tools like Effect Chain, which allow you to apply multiple effects at a time
  • Use one of the many other NCH multimedia applications that are integrated with MixPad.
npm install playwright
npx playwright install chromium

This script waits for the page to settle, selects print media, and writes a PDF:

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({ headless: true });
  try {
    const page = await browser.newPage({
      viewport: { width: 1440, height: 900 },
      deviceScaleFactor: 1
    });
    await page.goto('https://example.com/report', { waitUntil: 'networkidle' });
    await page.pdf({
      path: 'report.pdf',
      format: 'A4',
      printBackground: true,
      margin: { top: '18mm', right: '14mm', bottom: '18mm', left: '14mm' }
    });
  } finally {
    await browser.close();
  }
})();

Use a selector-based wait instead of relying only on network idle when your application renders after a websocket, timer, or client-side state change:

await page.goto('https://example.com/report', { waitUntil: 'domcontentloaded' });
await page.waitForSelector('[data-report-ready]', { state: 'visible' });
await page.pdf({ path: 'report.pdf', format: 'A4', printBackground: true });

Puppeteer example (Node.js)

Install Puppeteer, which downloads a compatible browser for its normal setup:

npm install puppeteer
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: 'new' });
  try {
    const page = await browser.newPage();
    await page.goto('https://example.com/report', { waitUntil: 'networkidle2' });
    await page.pdf({
      path: 'report.pdf',
      format: 'A4',
      printBackground: true,
      margin: { top: '18mm', right: '14mm', bottom: '18mm', left: '14mm' }
    });
  } finally {
    await browser.close();
  }
})();

Puppeteer’s PDF method uses the print CSS media type by default and waits for fonts. If the design only looks correct under screen styles, call await page.emulateMediaType('screen') before generating the PDF. Browser print also modifies colors; add -webkit-print-color-adjust: exact in your print stylesheet when preserving authored colors is necessary.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

CSS that prevents common surprises

@page {
  size: A4;
  margin: 18mm 14mm;
}

@media print {
  .screen-only { display: none !important; }
  .avoid-break { break-inside: avoid; }
  h2 { break-after: avoid; }
  body { -webkit-print-color-adjust: exact; }
}

For charts, wait for the chart library’s own “ready” signal or a DOM marker. For images loaded lazily, scroll or trigger the application’s image loader before printing. For authenticated pages, create a browser context with the required cookies or headers and never log those credentials.

Print-first engines without a browser binary

WeasyPrint (Python)

WeasyPrint is a strong fit for controlled, print-oriented HTML and CSS where client-side JavaScript is unnecessary. Install it according to your operating system’s documented native dependencies, then:

pip install weasyprint
from weasyprint import HTML

HTML('https://example.com/report').write_pdf('report.pdf')

You can also render a local template with an explicit base URL so relative stylesheets and images resolve:

from weasyprint import HTML

HTML(string=html, base_url='/srv/report-assets').write_pdf('report.pdf')

Choose WeasyPrint when deterministic pagination outweighs executing page JavaScript. A page that depends on React hydration or a canvas chart should be rendered by a browser first, or redesigned as server-generated markup and images.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Paged.js, Vivliostyle CLI, and OpenHTMLtoPDF

Paged.js and Vivliostyle CLI implement browser-oriented paged-media workflows and are useful when CSS page rules, generated content, and book-like layout are central. OpenHTMLtoPDF is a Java option for teams that want a library rather than a browser process. The comparison material also lists dompdf, mPDF, xhtml2pdf, and OpenHTMLtoPDF as options when avoiding a browser binary. Confirm each engine’s supported CSS, font handling, and JavaScript limitations against your templates; “HTML support” is not interchangeable across engines.

Managed PDF APIs and browser services

When an API is the better architecture

A managed service can remove browser image maintenance, worker autoscaling, queueing, and much of the patching responsibility from your application. This is attractive for bursty jobs or teams that cannot dedicate an operations path to Chromium. Doppio’s 2026 options guide presents managed APIs as a practical choice for many projects, especially those needing reliability, multiple languages, or high volume; that is a vendor opinion, not an independent market finding.

Browserless

Browserless documents exporting any webpage or HTML as PDF through a REST /pdf endpoint and browser connections for waiting on dynamic content. Its examples include A4 output, print backgrounds, headers, and footers, and show both Puppeteer and Playwright connections. Before committing, check current authentication, limits, data residency, retention, and contractual availability for your region.

Doppio

Doppio describes three approaches—legacy wkhtmltopdf, self-hosted Puppeteer/Playwright, and managed HTML-to-PDF APIs—and positions managed APIs as a way to avoid maintaining Chrome, scaling workers, and security controls yourself. Treat those statements as vendor claims and validate them with a representative document and your own compliance requirements.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why wkhtmltopdf should usually be a migration target

Comparison sources describe wkhtmltopdf as archived in 2023, warn about unpatched CVEs, and note that it lacks modern JavaScript and CSS support. A legacy static template may still render acceptably, so migration should be controlled rather than a blind replacement.

  1. Capture PDFs from representative templates, including long tables, fonts, images, and failure cases.
  2. Implement the new renderer beside the old one and compare text extraction, page count, visual diffs, and links.
  3. Review sandboxing, outbound network access, secrets exposure, and patch cadence.
  4. Switch traffic gradually, retaining a rollback path until business owners accept the differences.

Performance, throughput, and cost

Browser startup dominates cold jobs. Keep a bounded pool of warm workers, reuse contexts when isolation permits, and cap concurrency so memory pressure does not turn into timeouts. Close pages and contexts, set navigation and PDF timeouts, and record document duration, browser version, page URL, and failure reason.

A PDF4.dev 2026 benchmark reports a complex document at 13 ms on a warm Playwright browser instance, 58 ms for Puppeteer, and 629 ms for WeasyPrint. Those are workload-specific figures from one publisher, not a universal ranking; your templates, fonts, network, hardware, and warm-up policy can reverse the result.

Self-hosting has no per-document vendor fee but carries engineering costs for browser images, security patches, scaling, observability, and retries. A managed API converts much of that into usage pricing and contractual limits. Compare total cost per successful PDF, not just the headline request price, and include failed-job behavior, storage, egress, and support.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Security and reliability checklist

  • Run browser workers in a sandboxed, least-privilege environment with restricted outbound access.
  • Do not expose internal metadata services or private network ranges to arbitrary user-supplied URLs.
  • Keep authentication headers and cookies out of logs and error payloads.
  • Pin and patch browser and system packages; rebuild images regularly.
  • Set navigation, resource, and overall job timeouts. Retry only failures that are safe to retry.
  • Record whether a job failed during navigation, asset loading, layout, or file upload.
  • Use deterministic fonts and assets when legal or regulatory output must be reproducible.
  • For a managed service, verify region, retention, encryption, quotas, SLA, webhook security, and deletion behavior.

Common failures and fixes

The PDF is blank or missing chart data

The capture happened before hydration or chart painting. Wait for a page-specific ready selector, network completion plus a short application-controlled signal, or an explicit chart-render event. Do not rely on a fixed delay as your only synchronization method.

Styles look different from the website

Print media is active by default in Puppeteer. Add print rules deliberately, or emulate screen media when that is the intended design. Check that every stylesheet, font, and image URL is reachable from the renderer.

Rank #4
DeskFX Free Audio Effects & Audio Enhancer Software [PC Download]
  • Transform audio playing via your speakers and headphones
  • Improve sound quality by adjusting it with effects
  • Take control over the sound playing through audio hardware

Fonts fall back or text reflows

Wait for document.fonts.ready when using custom browser code, verify font responses are successful, and package licensed fonts with the worker when external loading is unreliable. WeasyPrint and browser engines may support different font formats and CSS features, so test the actual files.

Long tables split badly

Use print CSS such as break-inside: avoid on rows or grouped blocks where supported, repeat table headers, and test rows that span multiple pages. If pagination rules are the central requirement, a paged-media engine may be a better fit than a browser.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Navigation times out

Find the blocking request in network logs. Permit required domains, block unnecessary trackers, and distinguish a slow origin from a page that never reaches the expected state. A retry should use a fresh page or context when the first navigation left corrupted state.

Self-hosted workers run out of memory

Lower concurrency, recycle workers after a bounded number of jobs, close every page, and avoid loading unbounded asset sets. Measure warm and cold memory separately before selecting worker limits.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If you need a hosted capture endpoint, ScreenshotNeo is the first alternative to try: it removes consent banners, newsletter popups, and chat widgets before capture, bills only clean shots, and has a $5 paid plan for 3,000 shots.

It can return PNG, JPEG, WebP, or PDF from one GET request. The same service supports full-page captures, lazy-image loading, CSS-selector element capture, device and viewport settings, retina scale, PDF paper size and margins, page ranges, custom CSS and JavaScript, clicks, waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, TTL caching, signed links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and each response identifies the page verdict and billing status in headers. Every feature is on every plan: 1,000 shots per month are free with no card; paid plans start at $5 for 3,000. Yearly billing provides two months free.

Best Value
WavePad Audio Editing Software - Professional Audio and Music Editor for Anyone [Download]
  • Full-featured professional audio and music editor that lets you record and edit music, voice and other audio recordings
  • Add effects like echo, amplification, noise reduction, normalize, equalizer, envelope, reverb, echo, reverse and more
  • Supports all popular audio formats including, wav, mp3, vox, gsm, wma, real audio, au, aif, flac, ogg and more
  • Sound editing functions include cut, copy, paste, delete, insert, silence, auto-trim and more
  • Integrated VST plugin support gives professionals access to thousands of additional tools and effects
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com/report -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://example.com/report"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com/report' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

See the ScreenshotNeo documentation for response and PDF options, then create a free account to use 1,000 screenshots each month with no card.

A practical selection process

  1. Render one representative document with your real fonts, charts, images, and authentication flow.
  2. Decide whether JavaScript execution is mandatory. If yes, start with Playwright or Puppeteer; if no, measure a paged-media engine.
  3. Measure cold start, warm throughput, peak memory, failure rate, and page-to-page visual differences under your expected concurrency.
  4. Choose self-hosting only if your team can own browser patching, isolation, observability, and capacity.
  5. Choose a managed API only after checking residency, retention, quotas, SLA, retries, webhook security, and total cost.
  6. Keep golden PDFs and automated visual or text checks so renderer upgrades do not silently change regulated or customer-facing documents.

Frequently Asked Questions

Does Puppeteer wait for web fonts before creating a PDF?

Its documented PDF method waits for fonts by default. You should still verify font responses and test your own custom-font files.

When is a paged-media engine preferable to Chromium?

Choose one when templates are mostly static and repeatable pagination, running content, and print rules matter more than executing client-side JavaScript.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Is the 2026 Playwright benchmark a guaranteed speed ranking?

No. The 13 ms, 58 ms, and 629 ms figures come from one PDF4.dev workload on warm instances and should not be generalized to every document or deployment.

What should I test before replacing wkhtmltopdf?

Use representative templates and compare page count, text, links, fonts, images, long-table breaks, security controls, and rollback behavior in a side-by-side rollout.

Quick Recap

Bestseller No. 1
MixPad Free Multitrack Recording Studio and Music Mixing Software [Download]
MixPad Free Multitrack Recording Studio and Music Mixing Software [Download]
Create a mix using audio, music and voice tracks and recordings.; Customize your tracks with amazing effects and helpful editing tools.
Bestseller No. 4
DeskFX Free Audio Effects & Audio Enhancer Software [PC Download]
DeskFX Free Audio Effects & Audio Enhancer Software [PC Download]
Transform audio playing via your speakers and headphones; Improve sound quality by adjusting it with effects

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.