Skip to content

§ Wkhtmltopdf alternative

Wkhtmltopdf Alternative: What to Run Now the Project Is Dead

The last wkhtmltopdf release shipped in June 2020 and the repository was archived in January 2023. If it is still in your stack, this page maps the six real replacements, by language and by how much infrastructure you want to own.

Try the free converter
  • Early access, launching soon
  • No card required
  • Your HTML stays yours

§ Short answer

The best wkhtmltopdf alternative depends on your stack. wkhtmltopdf was archived in January 2023, its last release (0.12.6) shipped in June 2020, and it carries an unpatched server side request forgery vulnerability rated 9.8, CVE-2022-35583. For Python apps rendering static templates, WeasyPrint is the healthiest library. For JavaScript heavy pages, Playwright or Puppeteer render in real Chromium. For a self hosted HTTP service, Gotenberg wraps Chromium in Docker. And if you do not want to operate a browser at all, a managed API such as Sitepdf does the render and keeps a timestamped archive of the page in the same call.

Last updated July 2026. Written and fact checked by the Sitepdf team.

§ 00

The six real wkhtmltopdf replacements, compared

wkhtmltopdf facts are from the project's own GitHub repository, read on 16 July 2026. Sitepdf is in early access and its pricing is labelled planned; everything else here is shipped software you can install today.

Replacement Engine JavaScript pages What you operate Best for
WeasyPrint Its own CSS engine, pure Python No JS execution at all A Python dependency Static templates, invoices, print CSS
Playwright / Puppeteer Real Chromium Full support A browser fleet: memory, fonts, zombie processes JS heavy pages, teams with ops capacity
Gotenberg Chromium and LibreOffice in Docker Full support A container and its scaling A self hosted HTTP service behind your firewall
PrinceXML / DocRaptor PrinceXML Limited; Prince is not a browser Nothing (DocRaptor) or a license (Prince) Print grade typography: books, filings, manuals
Headless Chrome CLI Real Chromium Full support Chrome versions and flags on every host Quick scripts and CI jobs
Sitepdf Managed Chromium Full support, plus wait_for selector Nothing Rendering plus a timestamped archive of every page

The wrappers inherit the problem: pdfkit (Python), wicked_pdf (Rails), laravel-snappy (PHP) and DinkToPdf (.NET) all shell out to the same archived wkhtmltopdf binary. Migrating the wrapper without replacing the engine changes nothing.

§ 01

Wkhtmltopdf is not aging, it is archived

Three dates tell the story. June 2020: version 0.12.6, the final release. January 2023: the maintainers archive the GitHub repository and state plainly that the project is no longer maintained. Since then: nothing, including no patch for CVE-2022-35583, a server side request forgery hole rated 9.8 out of 10. If your service renders HTML that users influence, that vulnerability lets a crafted page make requests from inside your network. There is no version you can upgrade to that fixes it.

The engine problem is older than the abandonment. wkhtmltopdf wraps a Qt WebKit build whose CSS support froze years before the project did: no CSS grid at all, flexbox that half works, and page break handling that slices table rows in two. Every stylesheet your team writes today is written for browsers that left that engine behind a decade ago, so the gap between what designers build and what the PDF shows only widens. We wrote up the whole self hosting math in library versus API if you want the long version.

§ 02

Check your wrappers: you may be running it without naming it

Most production wkhtmltopdf does not say wkhtmltopdf anywhere in the application code. It says pdfkit in a Python requirements file, wicked_pdf in a Rails Gemfile, laravel-snappy in a composer.json, or DinkToPdf in a .NET project. All of them are thin wrappers that shell out to the same archived binary, usually installed by a Dockerfile line nobody has read since 2021.

The quick audit: search your images for the binary itself. grep -r wkhtmltopdf Dockerfile* in your repos, or which wkhtmltopdf on a production host. If it is there, the January 2023 archive notice and the unpatched SSRF apply to you, whatever the wrapper is called.

§ 03

Pick by stack, not by leaderboard

Python: if your templates are static HTML and CSS, WeasyPrint is the healthy choice: actively maintained, pure Python, and genuinely good at print CSS such as page breaks and running headers. If your pages need JavaScript to finish rendering, WeasyPrint sees an empty shell and you want Playwright instead. Our Python HTML to PDF guide walks every option with code.

Node: you are one dependency away from Puppeteer or Playwright anyway; the question is not the library but whether you want to operate the browser fleet behind it. That math is in the Puppeteer alternative breakdown.

PHP, Ruby and C#: there is no healthy native engine. Dompdf renders pure PHP but skips JavaScript and chokes on modern CSS; DinkToPdf is the dead binary again. Realistic options are a Gotenberg container next to your app, a headless browser via Playwright bindings, or a rendering API.

Print typography: if your documents need running headers, page counters and widow control, that is PrinceXML territory, and we would rather point you at our honest DocRaptor comparison than pretend Chromium does typesetting.

§ 04

What migration actually breaks, so you can test for it

Moving from frozen WebKit to modern Chromium is mostly an upgrade, but four things bite. First, CSS written around the old engine's bugs: vendor prefixed flexbox, table based layout hacks, zoom factors tuned to its odd DPI handling. They render differently, sometimes better, always differently. Second, page breaks: page-break-inside: avoid and friends behave more correctly in Chromium, which can shift pagination on long documents. Third, header and footer flags: wkhtmltopdf's --header-html and --footer-center options map to header and footer templates in modern engines, not one to one flags. Fourth, fonts: the new renderer resolves fonts differently, so anything not explicitly loaded as a web font may swap.

The test that catches all four: pick ten real documents from production, render each through the old and new pipeline, and put the pairs side by side. An afternoon of diffing beats a month of support tickets.

§ 05

The API option: replace the binary with one HTTP call

Every self hosted replacement above still leaves you operating something: a Python dependency chain, a browser fleet, a Docker container. The alternative is to make rendering someone else's pager duty. One call to Sitepdf sends a URL or raw HTML and returns a pixel perfect PDF from managed Chromium, with wait_for holding the render until your content is actually on screen.

And because the reason many wkhtmltopdf deployments exist is records, invoices, statements, confirmations, the same call can store a timestamped, retrievable snapshot of what was rendered: add archive=true and the dated record is kept under your account. The PDF generator API page covers generating from templates, and URL to PDF covers live pages.

The whole migration, if you go the API route: the binary becomes one call.
curl https://api.sitepdf.com/v1/render \
  -H "Authorization: Bearer $SITEPDF_KEY" \
  -F [email protected] \
  -F format=A4 \
  -F margin=normal \
  -F archive=true

{
  "pdf_url": "https://api.sitepdf.com/v1/documents/doc_2kd83.pdf",
  "archive": {
    "id": "arc_b81mm",
    "captured_at": "2026-07-16T08:41:37Z",
    "retrieve_url": "https://api.sitepdf.com/v1/archives/arc_b81mm"
  }
}

The API is in early access; this is the documented call shape it opens with. Full request and response walkthrough.

§ 06

Questions about this job

Is wkhtmltopdf still maintained?
No. The GitHub repository was archived in January 2023 with a notice that the project is no longer maintained. The final release, 0.12.6, shipped in June 2020. No bug fixes or security patches have been published since, and none are coming.
Is wkhtmltopdf safe to use in production?
Not if it touches input users can influence. CVE-2022-35583, a server side request forgery vulnerability rated 9.8, remains unpatched because the project is archived. A crafted page can make the renderer issue requests from inside your network. Rendering only fully trusted, static templates reduces the exposure but the hole itself will never be fixed.
What is the best wkhtmltopdf alternative for Python?
WeasyPrint for static templates: pure Python, actively maintained, strong print CSS. Playwright for pages that need JavaScript to finish rendering. Note that pdfkit is not an alternative; it is a wrapper that shells out to the same archived wkhtmltopdf binary.
What is the best wkhtmltopdf alternative for PHP?
There is no healthy native PHP engine. Dompdf works for simple, static documents but executes no JavaScript and struggles with modern CSS. For real pages the practical options are a Gotenberg container beside your app, a headless browser, or a rendering API called from your Laravel or Symfony code. laravel-snappy is the dead binary in disguise.
What is the best wkhtmltopdf alternative for C#?
DinkToPdf wraps the same archived binary, so it inherits every problem including the unpatched SSRF. The maintained paths are Playwright for .NET driving real Chromium, a commercial Chromium library, or an HTTP rendering API, which keeps browser operations out of your deployment entirely.
Does wkhtmltopdf support CSS grid or flexbox?
No grid at all, and flexbox only partially, with bugs. The Qt WebKit build inside wkhtmltopdf froze before CSS grid existed. Stylesheets written for current browsers will lay out incorrectly, which is why teams keep a separate, simplified template just for their PDFs, and why they eventually migrate.

§ 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.

Render + archive, one API