Convert HTML to PDF with wkhtmltopdf

25 June 2025
This post thumbnail

Quick Start

wkhtmltopdf is a command-line tool that converts HTML to PDF. It’s been around for years and is probably the most popular tool in it’s category.

To get started, you can download it from the wkhtmltopdf releases page on github.

Basic usage:

# Convert a website to PDF
wkhtmltopdf https://transformy.io transformy.pdf

# Convert local HTML file
wkhtmltopdf index.html output.pdf

# Add margins and headers
wkhtmltopdf --margin-top 20mm --header-right "Page [page]" https://transformy.io output.pdf

What is wkhtmltopdf?

wkhtmltopdf is a command-line tool that converts HTML to PDF using the QT WebKit rendering engine. Similarly to a browser, it can render HTML, CSS and Javascript. It comes with a very easy to use API, runs headless, and is relatively easy to integrate into your existing stack. The license (GPL v3.0) is also very permissive.

Be warned though: wkhtmltopdf relies on QT webkit which isn’t actively maintaned anymore. This means that rendering issues might pop up considering how fast web technologies evolve. Sites built with modern JavaScript frameworks or SPAs (React, Vue…) in particular might not render as expected. However, for most HTML documents and simpler websites, it works really well.

Installing wkhtmltopdf

First off you’ll need to install the package on your machine.

macOS

On macOS this used to be straightforward usign brew. But because wkhtmltopdf hasn’t been updated in a while, running brew install --cask wkhtmltopdf will give you the following error message:

Error: Cask 'wkhtmltopdf' has been disabled because it is discontinued upstream! It was disabled on 2024-12-16.

What you need to do instead:

  1. Head over to the releases page and download the relese for macOS.
  2. Double click on the .pkg file
  3. You’ll likely see another error: “Apple could not verify “wkhtmltox-0.12.6-2.macos-cocoa.pkg” is free of malware that may harm your Mac or compromise your privacy.”
  4. Close the error window and head on over to System Settings -> Privacy & Security -> Scroll down to Security. There, you’ll see a message saying the packages was blocked. Click on “Open Anyway”
  5. The installer should now have launched and you can continue with the installation.

wkhtmltopdf version output

Windows

For Windows installation:

  1. Download the installer from the releases page
  2. Run the installer

The installer will add wkhtmltopdf to your PATH automatically

Linux

On Linux the exact steps for installation will vary depending on your distro. Here’s how to get it running on Ubuntu 22.04

This is an example using amd64. Depending on your architecture you will need a different version. You can find all available versions on the releases page.

apt install wkhtmltopdf

wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-2/wkhtmltox_0.12.6.1-2.jammy_amd64.deb

sudo dpkg wkhtmltox_0.12.6.1-2.jammy_amd64.deb

Finally, make sure you don’t have any broken dependencies and run:

sudo apt install -f

Verify installation

wkhtmltopdf --version

wkhtmltopdf version output

If you see the version info, you’re good to go.

How to use wkhtmltopdf

Now that you have wkhtmltopdf installed, let’s look at how to use it. Every wkhtmltopdf command follows this structure:

wkhtmltopdf [options] <input> <output>

Common use cases

Converting a website to PDF:

wkhtmltopdf https://transformy.io/examples/blog/1/ blog-post.pdf

Blog post PDF preview

Converting a local HTML file:

wkhtmltopdf invoice.html invoice.pdf

Combining multiple pages into one PDF:

wkhtmltopdf page1.html page2.html page3.html combined.pdf

PDF with page numbers:

wkhtmltopdf --header-right "Page [page] of [toPage]" --header-line \
            --margin-top 15mm https://transformy.io/examples/blog/1/ output.pdf

PDF with page numbers preview

wkhtmltopdf advanced examples

So far I mostly covered basic usage commands which cover the most common use cases, but there’s also many advanced features in wkhtmltopdf which offer a lot of customization options for your PDFs.

Basic Page Layout Options

Setting page size and orientation:

# A4 landscape orientation
wkhtmltopdf --page-size A4 --orientation Landscape https://transformy.io/examples/blog/1/ blog-landscape.pdf

A blog post is probably not the best use case for landscape page orientation, but here’s the result:

Landscape A4 PDF preview

# A4 portrait - standard document format
wkhtmltopdf --page-size A4 --orientation Portrait https://transformy.io/examples/invoice/1/ invoice-portrait.pdf

Portrait is also the default mode. The invoice looks like this:

Portrait invoice PDF preview

Custom margins

You can set custom margins for all four sides of your document.

wkhtmltopdf --margin-top 20mm --margin-bottom 20mm --margin-left 15mm --margin-right 15mm https://transformy.io/examples/blog/1/ custom-margins.pdf

Custom margins PDF preview

Adding Headers and Footers

Adding custom headers and footers is also possible. For example, you can use this to add page numbers or a document title:

# Simple page numbers
wkhtmltopdf --footer-center "Page [page] of [toPage]" https://transformy.io/examples/blog/1/ blog-with-pages.pdf

Blog with page numbers PDF preview

# Professional header with title and page numbers
wkhtmltopdf --header-left "Company Report" --header-right "Page [page] of [toPage]" \
            --header-line --margin-top 20mm https://transformy.io/examples/blog/1/ professional-header.pdf

Professional header PDF preview

Working with Table of Contents

For long documents, you can auto-generate a table of contents. The table is based on the heading tags in the HTML.

# Document with cover page and TOC
wkhtmltopdf cover title.html toc https://transformy.io/examples/blog/1/ https://transformy.io/examples/blog/2/ content-with-toc.pdf

Document with cover and TOC PDF preview

# TOC with custom title
wkhtmltopdf toc --toc-header-text "Table of Contents" https://transformy.io/examples/blog/2/ content-with-toc-title.pdf

TOC with custom title PDF preview

Controlling Page Breaks

Sometimes you need to control where pages break. While this isn’t something that you can set using the wkhtmltopdf command line tool, you can easily enforce this change with some minor changes to your styling. You’ll need to add either page-break-before or page-break-inside to your markup.

<!-- Force a new page -->
<div style="page-break-before: always;">
    <h2>Chapter 2</h2>
    <p>This starts on a new page</p>
</div>

<!-- Keep content together -->
<table style="page-break-inside: avoid;">
    <tr><td>This table won't break across pages</td></tr>
</table>

Advanced Options

JavaScript-heavy sites:

Many modern websites load content dynamically with JavaScript. By default, wkhtmltopdf waits 200ms to capture the page, which in some cases might not be enough. You can overwrite this:

# Give JavaScript time to execute
wkhtmltopdf --javascript-delay 3000 https://transformy.io/examples/blog/1/ report.pdf

# Wait for specific status
wkhtmltopdf --window-status ready https://transformy.io/examples/blog/1/ output.pdf

The delay is in milliseconds. Start with ~3000 (3 seconds) and adjust based on the site’s loading time. Obviously this will have an impact on the total processing time.

In some cases you might not want to run javascript at all. You can disable it with --disable-javascript.

Authentication:

If you need to convert pages that require login:

# Basic auth
wkhtmltopdf --username user --password pass https://transformy.io/examples/blog/1/ report.pdf

# Cookie-based auth
wkhtmltopdf --cookie session_id "435843285" https://transformy.io/examples/blog/1/ report.pdf

# Bearer token
wkhtmltopdf --custom-header "Authorization" "Bearer <token>" https://transformy.io/examples/blog/1/ report.pdf

Quality and file size:

# High quality for printing
wkhtmltopdf --dpi 300 https://transformy.io/examples/blog/1/ high-quality.pdf

# Optimized for web
wkhtmltopdf --lowquality --image-quality 75 https://transformy.io/examples/blog/1/ optimized.pdf

HTML Headers and Footers

For complex layouts, use HTML files for headers and footers:

# Create header.html and footer.html files
wkhtmltopdf --header-html header.html --footer-html footer.html \
            --margin-top 20mm --margin-bottom 20mm \
            https://transformy.io/examples/blog/1/ custom-layout.pdf

Custom layout PDF preview

Your header.html can include images, styling, and complex layouts:

<!DOCTYPE html>
<html>
<head>
    <style>
        body { margin: 0; font-family: Arial; font-size: 12px; }
        .header { border-bottom: 1px solid #ccc; padding: 10px; }
    </style>
</head>
<body>
    <div class="header">
        <img src="logo.png" height="30px" style="float: left;">
        <div style="float: right;">Page [page] of [toPage]</div>
        <div style="clear: both;"></div>
    </div>
</body>
</html>

Common issues and solutions

While implementing wkhtmltopdf for transformy, I’ve run into some small issues.

Poor font rendering

Installing proper fonts usually fixes this:

# Ubuntu/Debian
sudo apt-get install fonts-liberation

# CentOS/RHEL
sudo yum install liberation-fonts

CSS files not loading

Ensure your HTML uses absolute paths or includes a base tag. If you don’t own the website and aren’t able to add a base tag, you might need some pre-process to edit the html before passing it to wkhtmltopdf.

<base href="https://transformy.io/">

When wkhtmltopdf might not be enough

wkhtmltopdf is a workhorse, but there’s some scenarios where you might need to grab a different solution.

For one, it doesn’t support interactive PDF forms. If that’s something you need I recommend trying pdftk.

As mentioned earlier though, the biggest issue will be javascript heavy websites. In that case the a better solution is to use Headless Chrome to print your pages.