HTML to PDF in Python
Four ways to turn HTML into a PDF in Python — with code, honest trade-offs, and guidance on which to reach for.
The right tool depends on one question above all: does your HTML rely on JavaScript? Pure-Python libraries like WeasyPrint are fast and dependency-light but can't run JS. If your page renders content client-side — dashboards, charts, anything dynamic — you need a real browser engine, which means either hosting headless Chromium yourself or calling a hosted API. Here are the four common options.
1. WeasyPrint
Pure Python · strong print CSS · no JavaScript
WeasyPrint is a pure-Python library with excellent support for print CSS (paged media, page breaks, headers/footers). It installs via pip with no external binary. The catch: it does not execute JavaScript, so anything rendered client-side — charts, JS-driven layouts — won't appear. Ideal for server-side templates you fully control.
# pip install weasyprint
from weasyprint import HTML
# From an HTML string
HTML(string="<h1>Invoice #123</h1>").write_pdf("invoice.pdf")
# Or straight from a URL
HTML("https://example.com").write_pdf("page.pdf")2. pdfkit + wkhtmltopdf
Wraps a system binary · renders some JS · binary unmaintained
pdfkit is a thin Python wrapper around the wkhtmltopdf command-line tool. It renders with an older WebKit engine and handles some JavaScript, but it requires installing the wkhtmltopdf binary separately (not pure pip). Note that the wkhtmltopdf project has been archived and is no longer actively maintained, so its engine keeps falling further behind modern browsers.
# pip install pdfkit
# also requires the wkhtmltopdf binary on the system
import pdfkit
pdfkit.from_string("<h1>Invoice #123</h1>", "invoice.pdf")
pdfkit.from_url("https://example.com", "page.pdf")3. xhtml2pdf
Pure Python · simple · limited CSS
xhtml2pdf is another pure-Python option, easy to install and use for straightforward documents. Its CSS support is more limited than WeasyPrint's and it doesn't run JavaScript, so it's best for simple, predictable templates rather than complex modern layouts.
# pip install xhtml2pdf
from xhtml2pdf import pisa
with open("invoice.pdf", "wb") as f:
pisa.CreatePDF("<h1>Invoice #123</h1>", dest=f)4. Rendershot (hosted API)
Real Chromium · runs JS · no system deps or browser to host
If you'd rather not install a binary or run a headless browser, a hosted API renders on real Chromium for you. You POST HTML or a URL and get back PDF bytes — JavaScript executes, fonts and lazy-loaded content resolve, and there's nothing to scale on your side. It's a paid service (with a free tier), so it suits production workloads more than a one-off script.
# pip install httpx
import httpx
resp = httpx.post(
"https://api.rendershot.io/v1/pdf",
headers={"X-API-Key": "sk_live_..."},
json={"html": "<h1>Invoice #123</h1>", "format": "pdf"},
)
with open("invoice.pdf", "wb") as f:
f.write(resp.content)Which should you use?
- Server-side templates, no JS: WeasyPrint — pure Python, great print CSS, nothing extra to install.
- Simple documents: xhtml2pdf if WeasyPrint is more than you need.
- JS-heavy pages or pixel accuracy: a Chromium-based path — headless Chrome you host, or a hosted API like Rendershot if you'd rather not run a browser.
- Avoid for new projects: pdfkit/wkhtmltopdf, since the underlying binary is unmaintained — unless you already depend on it.
HTML to PDF in Python — FAQ
What's the best way to convert HTML to PDF in Python?
It depends on your content. WeasyPrint is best for pure-Python rendering with strong print CSS but no JavaScript. For JavaScript-heavy pages or pixel-accurate output, a headless-Chromium approach or a hosted API renders most reliably. pdfkit/wkhtmltopdf was long popular but its underlying binary is no longer maintained.
Does WeasyPrint support JavaScript?
No. WeasyPrint renders HTML and CSS but does not execute JavaScript, so client-side-rendered content and charts won't appear. Use a Chromium-based option (headless Chrome or a hosted API like Rendershot) when you need JS to run.
Is wkhtmltopdf still maintained?
No — the wkhtmltopdf project has been archived and is no longer actively maintained, and it uses an aging WebKit engine. The pdfkit Python wrapper still works but inherits those limitations, so it's worth weighing against modern alternatives.
How do I convert HTML to PDF in Python without system dependencies?
Use a hosted API: pip install httpx (or the Rendershot SDK), POST your HTML to the /v1/pdf endpoint, and write the returned bytes to a file. There's no wkhtmltopdf binary to install and no local browser to run or scale.
Can I convert a URL to PDF in Python, not just an HTML string?
Yes. WeasyPrint accepts a URL, pdfkit has from_url, and Rendershot takes a url parameter. For JavaScript-heavy pages, a Chromium-based option renders the URL most accurately.
HTML to PDF without the dependencies
Render PDFs on real Chromium via one API call. Free plan: 200 renders/month, no card.
Start for free →