# wkhtmltopdf alternative: modern HTML to PDF API

wkhtmltopdf alternative: the project is archived and stuck on QtWebKit. Switch to a Chromium PDF API with flexbox, grid and web fonts.

**Quick answer.** Replace the `wkhtmltopdf` command with one HTTP call to a Chromium renderer.

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

## Is wkhtmltopdf still maintained?

No, and this section explains why that matters. The `wkhtmltopdf/wkhtmltopdf` GitHub repository was **archived by its owner on January 2, 2023** and is read-only. No more fixes or releases are coming, including security fixes.

The bigger problem is older than that. wkhtmltopdf renders with **QtWebKit**, a WebKit fork that stopped tracking modern browsers years ago. In practice you get these issues.

- **No CSS Grid** and no modern **flexbox**. Layouts that work in every browser collapse or overlap.
- Spotty support for modern JavaScript (ES6+), so charts and client-rendered pages often come out blank.
- CSS variables, `@font-face` edge cases and newer selectors behave differently from a real browser.
- You debug against an engine nobody else uses. What you see in Chrome is not what you get in the PDF.

If your templates are full of tables and floats because "that's what works in wkhtmltopdf", that's the symptom.

## Your options in 2026

You have two realistic paths. You can run Chromium yourself or call a hosted API.

### 1. Self-host headless Chromium (Puppeteer, Playwright or Gotenberg)

Running Chromium yourself gives you a modern engine and full control. These are the tradeoffs.

- **Operations:** Chromium is a large binary with many system dependencies. It needs fonts installed, sandbox flags in containers, and enough memory per concurrent render.
- **Lifecycle:** you need to recycle browser processes, handle zombie processes and timeouts, and patch Chromium regularly for security fixes.
- **Serverless:** cold starts and package-size limits make Chromium on functions awkward. Most teams end up running a dedicated service.

[Gotenberg](https://gotenberg.dev) packages Chromium behind an HTTP API in a Docker image. It is a good choice if you want to self-host, and it's what html-pdf.com runs on.

### 2. Use a hosted API

Send HTML, get a PDF. There is no browser to run, patch or scale.

html-pdf.com uses **headless Chromium**, so flexbox, grid, web fonts and JavaScript render the way they do in Chrome. You pay per page (1 credit = 1 PDF page), from $0.01 down to $0.005 per page, in prepaid packs that never expire. There's no subscription, you get 100 free credits to start, and failed renders cost nothing.

## Migrating from the wkhtmltopdf CLI

This section shows a real command before and after the switch.

**Before:**

```bash
wkhtmltopdf --page-size A4 -O Landscape \
  -T 15mm -B 20mm -L 15mm -R 15mm \
  --javascript-delay 2000 \
  --footer-center "[page] / [topage]" --footer-font-size 9 \
  invoice.html invoice.pdf
```

**After:**

```bash
curl -X POST https://html-pdf.com/v1/pdf \
  -H "Authorization: Bearer $HTML_PDF_KEY" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html invoice.html '{
        html: $html,
        format: "A4",
        landscape: true,
        margin: {top: "15mm", bottom: "20mm", left: "15mm", right: "15mm"},
        wait_delay: 2,
        footer_html: "<div style=\"font-size:9px;width:100%;text-align:center\"><span class=\"pageNumber\"></span> / <span class=\"totalPages\"></span></div>"
      }')" \
  -o invoice.pdf
```

`jq --rawfile` safely puts your HTML file into the JSON body. If your HTML references local images or CSS, upload them together with a multipart request.

```bash
curl -X POST https://html-pdf.com/v1/pdf -H "Authorization: Bearer $HTML_PDF_KEY" \
  -F "index.html=@invoice.html" -F "logo.png=@logo.png" -F "style.css=@style.css" \
  -F 'options={"format":"A4","landscape":true,"margin":"15mm"}' \
  -o invoice.pdf
```

To convert a URL (the equivalent of `wkhtmltopdf https://example.com out.pdf`), send `{"url": "https://example.com"}`. This works for public pages only.

### Option mapping

| wkhtmltopdf | html-pdf.com |
|---|---|
| `--page-size A4` | `"format": "A4"` (A3 to A6, Letter, Legal, Tabloid) |
| `--page-width` / `--page-height` | `"width"` / `"height"` |
| `-O Landscape` | `"landscape": true` |
| `-T -B -L -R` | `"margin": {"top","bottom","left","right"}` or `"margin": "10mm"` |
| `--header-html` / `--footer-html` | `"header_html"` / `"footer_html"` (inline HTML; needs a margin) |
| `[page]` / `[topage]` | `<span class="pageNumber"></span>` / `<span class="totalPages"></span>` |
| `[date]`, `[title]` | `<span class="date"></span>`, `<span class="title"></span>` |
| `--javascript-delay 2000` (ms) | `"wait_delay": 2` (seconds, 0 to 10) |
| `--window-status ready` | `"wait_for_expression": "window.status === 'ready'"` |
| `--print-media-type` | `"media": "print"` (or `"screen"` for the on-screen look) |
| `--zoom 0.8` | `"scale": 0.8` |
| `--no-background` | `"print_background": false` |
| `--user-style-sheet` | `"css": "..."` |

### Things to retest after switching

A few things render differently in Chromium, so check them once.

- **Page breaks:** use `break-before: page` and `break-inside: avoid`. Chromium respects them more consistently than old `page-break-*` hacks in WebKit.
- **Scale:** wkhtmltopdf's "smart shrinking" made content smaller. Chromium prints at true size, so you may need `scale` or CSS adjustments.
- **Header and footer styles:** Chromium renders headers and footers in a separate context. Put font sizes and styles inline in `header_html` and `footer_html`.

## When to keep self-hosting

An API isn't always the right answer. Keep rendering in-house in these cases.

- Documents must **never leave your network** for compliance reasons. Run Gotenberg or Playwright on your own infrastructure.
- You need **offline or air-gapped** rendering.
- Your volume is so high and steady that a dedicated renderer costs less than per-page pricing, and you have people to run it.
- You render pages that are **only reachable inside your network**. You can still fetch the HTML yourself and send it as `html`.

Otherwise, get a key, then open the link we email you to confirm your address. That adds 100 free credits.

```bash
curl -X POST https://html-pdf.com/v1/signup -H "Content-Type: application/json" -d '{"email": "you@example.com"}'
```

Full reference: [API docs](https://html-pdf.com/docs) · [MCP server](https://html-pdf.com/mcp)

## FAQ

### Is wkhtmltopdf still maintained?

No. Its GitHub repository was archived on January 2, 2023, so no more fixes or releases are coming, including security fixes.

### What should I use instead of wkhtmltopdf?

Use a Chromium-based renderer. You can self-host Puppeteer, Playwright or Gotenberg, or call a hosted API like html-pdf.com with `POST https://html-pdf.com/v1/pdf`.

### How do I add page numbers after leaving wkhtmltopdf?

Replace `[page]` and `[topage]` with `<span class="pageNumber"></span>` and `<span class="totalPages"></span>` inside `footer_html`, and leave a bottom margin for it.

### How much does the html-pdf.com API cost?

1 credit = 1 PDF page, from $0.01 down to $0.005 per page in prepaid packs that never expire. You get 100 free credits to start, with no card, and failed renders cost nothing.
