Recommended Free Tools
For most new projects, Puppeteer with Chromium is the best wkhtmltopdf replacement when the source page uses JavaScript or must look like Chrome. Choose WeasyPrint for Python applications that produce controlled, print-oriented documents; choose Prince, PDFreactor or Antenna House when advanced paged-media features and vendor support justify commercial licensing. Use Gotenberg or a managed API when you want a service boundary instead of installing a renderer in every application.
Which wkhtmltopdf alternative should you choose?
The right replacement depends on what your HTML needs after the initial request. A page that builds its content in JavaScript needs a real browser engine. An invoice or report rendered from a stable template usually benefits more from deterministic print CSS and pagination controls than from browser compatibility.
| # | Preview | Product | Price | |
|---|---|---|---|---|
| 1 |
|
99 Formatting Tips for Self-Published Authors: How to Self-Publish a Better Book Using Various Tips... | $5.95 | Buy on Amazon |
| Option | Best fit | JavaScript | Primary integration | Main trade-off |
|---|---|---|---|---|
| Puppeteer/Chromium | Dynamic sites, dashboards and Chrome-faithful output | Yes, through Chromium | Node.js; Chrome automation APIs | You operate a browser runtime and its memory footprint |
| WeasyPrint | Python reports, invoices, certificates and print templates | No client-side JavaScript engine | Python library and command line | Not a browser; authentication and cookies are not supported by default |
| Prince | High-end paged-media publishing | Verify the current release’s scripting capabilities | Commercial engine | Licensing and vendor terms |
| PDFreactor | Enterprise print layouts and support | Verify requirements with the vendor | Commercial engine or service | Commercial licensing |
| Antenna House | Print-grade, standards-focused publishing | Verify requirements with the vendor | Commercial engine | Commercial licensing and deployment planning |
| Gotenberg | Teams that want a self-hosted HTTP conversion service | Browser-based conversion path is available; validate your version | HTTP service | You operate containers, queues, limits and isolation |
| Managed API | Applications that should not run browsers or converters | Depends on the provider | HTTPS API | External dependency, data-residency and per-use cost decisions |
If you are replacing a command such as wkhtmltopdf input.html output.pdf, do not select only by command-line similarity. First classify the document:
- Client-rendered or interactive source: start with Puppeteer/Chromium.
- Server-rendered, print-focused source: start with WeasyPrint if your application is Python.
- Complex books, regulatory forms or magazine-style layouts: evaluate a commercial paged-media engine.
- Many applications or languages: put conversion behind Gotenberg or a managed API.
Why wkhtmltopdf is being replaced
wkhtmltopdf and wkhtmltoimage are open-source headless command-line tools built around the Qt WebKit engine. That makes them unlike current Chrome automation: they reproduce an older WebKit rendering model rather than the browser behavior most users see today.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →#1 Best Overall
A migration guide published in 2026 reports that the project was archived in January 2023 and that version 0.12.6 was released in 2020. Those dates explain why modern JavaScript, CSS and browser APIs can render differently or fail outright. The same guide reports an unpatched CVSS 9.8 SSRF issue. That is a secondary-source claim, not a formal security determination; confirm the exact package and vulnerability record in an authoritative database before making a security decision.
Replacing it is therefore about more than visual quality. You are also choosing a maintenance model, a runtime, an isolation boundary and a licensing posture.
Puppeteer: the browser-faithful replacement
Puppeteer is a JavaScript library for automating Chrome and Firefox through the Chrome DevTools Protocol and WebDriver BiDi. Its documented use cases include navigation, screenshots, UI testing and PDF generation. It is the strongest default when the page executes client-side JavaScript, loads data after navigation, uses modern web APIs or must match Chromium output.
Install and generate an A4 PDF
Install Puppeteer in a Node.js project. The package downloads a compatible browser unless you configure it to use an existing installation.
npm install puppeteer
Create render-pdf.mjs:
import puppeteer from 'puppeteer';
const url = process.argv[2] ?? 'https://example.com';
const browser = await puppeteer.launch({
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox']
});
try {
const page = await browser.newPage();
await page.setViewport({ width: 1440, height: 900, deviceScaleFactor: 1 });
await page.goto(url, { waitUntil: 'networkidle2', timeout: 90_000 });
await page.emulateMediaType('print');
await page.pdf({
path: 'output.pdf',
format: 'A4',
printBackground: true,
preferCSSPageSize: true,
margin: { top: '16mm', right: '14mm', bottom: '16mm', left: '14mm' }
});
} finally {
await browser.close();
}
Run it with node render-pdf.mjs https://your-site.example/report. networkidle2 is useful for applications that make a finite set of requests, but it is not a guarantee that every chart or lazy component is ready. For a known application, wait for a specific selector instead:
await page.goto(url, { waitUntil: 'domcontentloaded' });
await page.waitForSelector('[data-report-ready]', { timeout: 30_000 });
What to control in production
- Set an explicit navigation and selector timeout; otherwise a never-ending request can occupy a worker.
- Use
page.emulateMediaType('print')and provide print CSS with@page, page breaks and print-specific visibility rules. - Set a deterministic viewport, locale, timezone and color-scheme when output is compared in tests.
- Wait for fonts, images and charts. A selector that means “data loaded” is more reliable than a fixed sleep.
- Reuse a browser process for a controlled batch, but create an isolated page per job and close it in a
finallyblock. - Run the browser with a current, patched build and an appropriately restricted container. The
--no-sandboxflags above are convenient in some CI images; use the sandbox whenever your deployment permits it.
WeasyPrint: a strong Python choice for print documents
WeasyPrint is free and open source. It reads HTML and CSS, can load local and network resources, and produces PDFs with hyperlinks, bookmarks and attachments. Its design is document layout rather than browser automation, so it is a good match for invoices, reports, certificates and other controlled templates that do not require client-side JavaScript.
Minimal Python example
from weasyprint import HTML
HTML('https://example.com/report').write_pdf('report.pdf')
For generated HTML, pass a base URL so relative stylesheets, images and fonts resolve correctly:
from weasyprint import HTML
html = '''
Monthly report
Prepared for the customer.
'''
HTML(string=html, base_url='.').write_pdf('report.pdf')
Important limitations
- WeasyPrint does not execute client-side JavaScript. Render data on the server before handing HTML to it.
- Cookies and authentication are not supported by default. Fetch protected assets yourself, embed them, or configure an authenticated delivery path appropriate to your application.
- Use print CSS deliberately:
@page, named pages, counters, widows and orphans, and explicit break rules are where WeasyPrint can outperform a browser for structured documents. - Pin the WeasyPrint version and its native dependencies in deployment images, then test fonts and complex scripts on the target operating system.
Commercial paged-media engines
Prince, PDFreactor and Antenna House are candidates when CSS pagination is a central product requirement and the cost of licensing is justified by predictable output or enterprise support. They target advanced print-grade behavior such as complex page templates, running content and long-document control. Confirm current feature matrices, pricing, licensing scope and support terms directly with each vendor; those details vary by edition and can change.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallChoose this category when a browser renderer repeatedly needs workarounds for footnotes, running headers, cross-references, table splitting or book-length pagination. It is usually excessive for a simple web page or a small internal report.
Gotenberg and managed conversion services
Gotenberg provides a self-hosted HTTP-service path. Instead of linking a renderer into each application, your services submit jobs to a conversion container. This is useful when several languages need the same endpoint or when browser processes must be isolated from the main application.
Plan the service boundary explicitly: authenticate callers, cap input size and execution time, isolate untrusted URLs, define queue and concurrency limits, and decide where temporary files live. A managed HTML-to-PDF API removes browser and conversion-runtime operations from your team, but introduces provider dependency, data-residency review and usage pricing. Compare those operational costs with the engineering time required to patch and scale a self-hosted service.
Migration checklist from wkhtmltopdf
- Inventory inputs. Record whether each document is static HTML, JavaScript-rendered, authenticated, image-heavy or dependent on remote fonts.
- Capture the visual contract. Save representative PDFs, including long tables, page breaks, missing assets and right-to-left or non-Latin text where applicable.
- Choose the rendering model. Use Puppeteer for browser behavior, WeasyPrint for Python print layout, a commercial engine for advanced pagination, or a service for centralized operations.
- Replace implicit waits. Convert arbitrary delays into explicit readiness selectors, completed network requests or server-side data generation.
- Rework print CSS. Test
@page, margins, background colors, links, headers, footers and break rules in the new engine. - Handle assets and credentials. Decide how fonts, images, cookies, authorization headers and private APIs reach the renderer without exposing secrets in URLs.
- Compare at multiple sizes. Check one-page, multi-page and very long documents; pagination bugs often appear only after the first page.
- Set resource limits. Enforce timeouts, memory limits, maximum document size and a safe outbound network policy.
- Roll out by document type. Keep a fallback during migration, log renderer errors and compare output before switching every workload.
Reliability, security and cost decisions
JavaScript and fidelity
Browser rendering gives the closest result to what a Chrome user sees, but it also means browser startup, fonts, sandboxing and memory management. A layout engine can be more deterministic for controlled HTML/CSS because it does not run arbitrary page scripts.
Network access and secrets
Any renderer that can fetch URLs is an SSRF boundary. Restrict outbound destinations, block cloud metadata addresses, avoid putting credentials in query strings and sanitize user-supplied HTML. For private documents, prefer server-side data injection or short-lived, scoped credentials.
Cold starts and throughput
Launching a browser for every document increases latency. A warm, bounded pool improves throughput, while per-job pages preserve isolation. WeasyPrint and dedicated engines may have a smaller runtime footprint, but measure your own templates; no independent performance benchmark establishes a universal winner.
Licensing
WeasyPrint is free and open source. Puppeteer is a library used with browser binaries. Prince, PDFreactor and Antenna House require commercial licensing decisions. For a service, include container operations, monitoring, storage, queueing and provider charges in the total cost rather than comparing only a per-document number.
Or skip the browser setup
If your requirement is a clean capture or PDF from a public URL rather than an embedded renderer, ScreenshotNeo is the first managed alternative to try: it removes consent banners, newsletter popups and chat widgets before capture, bills only clean shots, and its paid plans start at $5 for 3,000 shots.
One GET request is enough for a URL capture. The endpoint can return PNG, JPEG, WebP or PDF; see the ScreenshotNeo documentation for the current output options.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo reports whether a response was a clean page, a bot check, a blank page, a timeout, a failed load or a cache hit through response headers; unsuccessful and cached cases are not billed. It also offers an MCP server with take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients. The free plan includes 1,000 screenshots per month with no card required. Create a free ScreenshotNeo account to try it.
Troubleshooting common migration failures
The PDF is blank
With Puppeteer, confirm the URL is reachable from the renderer, wait for a readiness selector and check console and request errors. With WeasyPrint, verify that the HTML is non-empty and that relative resources have the correct base_url.
Charts or client-rendered text are missing
Use Puppeteer and wait for the application’s completed-render marker. WeasyPrint will not execute the JavaScript that creates those elements; render the data on the server or switch engines.
Images or fonts disappear
Check URL resolution, TLS trust, content types and access controls. Embed assets or provide an authenticated resource path. In Puppeteer, wait for fonts and images before calling page.pdf().
Pages break in the wrong places
Move layout rules into print CSS, test break-before, break-after and break-inside, and remove fixed-height containers that cannot expand. For sophisticated running content and footnotes, evaluate a commercial paged-media engine.
The process hangs or consumes too much memory
Set navigation, selector and overall job timeouts; cap document size; close pages and browsers in cleanup code; and bound concurrency. A queue-backed service makes these limits easier to enforce consistently.
Private pages return a login screen
Supply authentication through a controlled browser context or server-side rendering. Do not expose long-lived tokens in page URLs. WeasyPrint does not provide cookie and authentication handling by default, so prepare authenticated assets before conversion.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
FAQ
Can I use the same HTML unchanged with every replacement?
No. Rendering engines differ in JavaScript execution, font handling and paged-media support. Treat your HTML and print CSS as a tested document contract, not a portable guarantee.
Is a managed API always cheaper than self-hosting?
No. It can reduce operations work, but request charges, bandwidth, storage and data-governance requirements may make self-hosting preferable at sustained volume.
What should I verify before approving a commercial engine?
Request a license quote and test your hardest documents: long tables, footnotes, running headers, embedded fonts, right-to-left text and accessibility requirements. Confirm redistribution and server-deployment terms in writing.
Frequently Asked Questions
Can I use the same HTML unchanged with every replacement?
No. Rendering engines differ in JavaScript execution, font handling and paged-media support, so test your HTML and print CSS as a document contract.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteIs a managed API always cheaper than self-hosting?
No. Compare request charges and governance requirements with the ongoing cost of operating browsers, containers, queues and monitoring.
What should I verify before approving a commercial engine?
Test difficult documents and confirm current licensing, redistribution and server-deployment terms directly with the vendor.
Quick Recap
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.




