Convert HTML to PDF with wkhtmltopdf

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:
- Head over to the releases page and download the relese for macOS.
- Double click on the .pkg file
- 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.”
- 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”
- The installer should now have launched and you can continue with the installation.

Windows
For Windows installation:
- Download the installer from the releases page
- 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

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
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
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:
# 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:
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
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
# 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
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
# TOC with custom title
wkhtmltopdf toc --toc-header-text "Table of Contents" https://transformy.io/examples/blog/2/ content-with-toc-title.pdf
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
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.









