wkhtmltopdf alternatives
wkhtmltopdf was archived on Jan 2, 2023 and is read-only. The direct replacement is browser rendering: headless Chromium prints the same HTML with modern CSS, web fonts, and JavaScript already applied. This guide maps every wkhtmltopdf flag to its browser equivalent, with per-language migration pages for Python, PHP, C#, Java, Go.
What happened to wkhtmltopdf
The wkhtmltopdf project was archived by the owner on Jan 2, 2023: the repository is read-only, releases have stopped, and with them the security fixes. The deeper consequence is the engine. wkhtmltopdf renders with a WebKit build from before flexbox and grid existed, so modern CSS silently falls back no matter how carefully the flags are tuned. That ceiling never moves again, because the code that would move it is archived.
Flag-by-flag migration
| wkhtmltopdf flag | Browser (Playwright/Chromium) equivalent |
|---|---|
--page-size A4 | page.pdf({ format: "A4" }) |
--orientation Landscape | page.pdf({ landscape: true }) |
--margin-* | page.pdf({ margin: { top, right, bottom, left } }) |
--zoom 1.5 | page.pdf({ scale: 1.5 }) |
--disable-smart-shrinking | nothing: Chromium does not smart-shrink; delete the workaround |
--print-background | page.pdf({ printBackground: true }) |
--header-html / --footer-html | page.pdf({ displayHeaderFooter: true, headerTemplate, footerTemplate }) |
--user-style-sheet style.css | page.addStyleTag({ path: "style.css" }) |
--javascript-delay 500 | page.waitForFunction() or waitUntil: "networkidle" |
--cookie name value | browserContext.addCookies([...]) |
| fonts installed on the server | web fonts via CSS @font-face, loaded by the page itself |
Pick by language
Each wrapper in each language is just a way of calling the same archived binary, so the migration is the same substitution everywhere with different syntax. Pick your language:
- Python: pdfkit is a thin subprocess around the wkhtmltopdf binary, so every call still renders through the frozen WebKit engine; the page maps each pdfkit option to the Playwright for Python API.
- PHP: snappy shells out to the same binary, so it inherits the archive date, the ended security fixes, and the CSS ceiling; the page shows the Chromium routes that work from PHP.
- C#: DinkToPdf P/Invokes the native wkhtmltopdf library, and the native library is the part that was archived; the page maps DinkToPdf settings to the Playwright for .NET API.
- Java: the JVM wrappers exec the same binary and stopped moving when the project did; the page shows the Playwright for Java equivalents for each wrapper call.
- Go: go-wkhtmltopdf wraps the binary in an exec call, so its output fidelity is capped where wkhtmltopdf stopped; the page maps its calls to Chromium rendering driven from Go.
Before and after, honestly
Chromium output differs from wkhtmltopdf output on legacy templates, and pretending otherwise is how migrations go wrong at 5pm on a Friday. On templates tuned over the years, most of the differences are deleted workarounds: the smart-shrink compensations, the JavaScript delays, the font installs that vanish once the page loads its own web fonts. Some differences are real layout changes from the newer engine, and those deserve eyes before you cut over. Each per-language migration page pairs the wrapper's before call with the same job in Playwright, so you can see exactly what changes before you commit.
Going deeper
Two companion guides: HTML to PDF without losing formatting covers why pages break in conversion and how to keep layout intact, and open source HTML to PDF APIs compared prices the free self-hosted routes against hosted ones. And if you would rather not run the renderer at all, the webcapture product page states engine, pricing, and a curl quick start. The recipes hub shows the same render call as runnable programs, one per page, in curl, Python, Node, and TypeScript.
Compare the engines head to head before you pick: Gotenberg vs Puppeteer, Gotenberg vs WeasyPrint, Gotenberg vs LibreOffice, and Puppeteer vs wkhtmltopdf.
Frequently asked questions
Is wkhtmltopdf still maintained?
No. The project was archived on Jan 2, 2023: the repository is read-only and no fixes have shipped since, including security fixes. The engine underneath is a WebKit build from before flexbox and grid existed.
What is the best wkhtmltopdf alternative?
Headless Chromium driven by Playwright. It prints the same HTML with JavaScript executed, web fonts loaded from the page, and modern CSS applied. The flag table above maps every old option to its equivalent, and each language page pairs the wrapper's before call with the Playwright after.
Do I need to rewrite my wkhtmltopdf flags?
Mostly a rename, not a rewrite: page size, orientation, margins, zoom, and print background each map to one option on the print call. The workarounds disappear instead of porting: Chromium does not smart-shrink, so the disable-smart-shrinking compensations are deleted.
Why do fonts disappear after migrating?
wkhtmltopdf printed with fonts installed on the server, so missing typefaces had to be installed system-wide. Chromium loads the page's own web fonts through @font-face, so the typefaces arrive with the page and the font installs leave the deployment.
Does Chromium still need --print-background?
The flag becomes printBackground: true on the print call. Hosted renderers usually print backgrounds by default; the per-request tuning moves to format, scale, page ranges, and header or footer templates.
Method
Checked 2026-09-11 against the wkhtmltopdf repository archive and the current Playwright print documentation.
Render your first page in seconds
Mint a key, POST a URL, and the finished document comes back in the same response; pass ?wait=false for a job ticket with poll and download URLs. The first 50 renders a month are free, and there is no credit card. Not ready for a key? The free URL to PDF tool renders public pages without one.