A curated list of awesome libraries, tools, and resources for converting HTML to PDF across various programming languages.
- Command Line & Headless Browsers
- Node.js / JavaScript
- Python
- PHP
- Ruby
- Go
- Java
- C# / .NET
- Rust
- Kotlin & Scala (JVM)
- Elixir
- Dart
- R
- Perl
- C / C++
- HTML to Markdown
- Markdown to PDF
- Online Services, Docker & APIs
- Print-CSS & Browser Libraries
- Specifications & Standards
- Low-Level PDF Libraries
- Engine Comparison
- Language Coverage Matrix
- Approaches: Pros and Cons
Tools that can be used across any language via CLI or API.
- Chromium / Google Chrome - Modern browsers have a built-in headless mode that can print DOM to PDF (
--headless --print-to-pdf). - wkhtmltopdf - A classic, open-source command line tool to render HTML into PDF using the Qt WebKit rendering engine. (Note: officially archived and no longer maintained).
- WeasyPrint - A smart HTML and CSS (and SVG) to PDF converter aiming to support web standards. Also works as a CLI tool.
- PrinceXML - Commercial software that converts HTML to PDF. Highly compliant with CSS standards.
- Pandoc - The universal document converter; converts Markdown/HTML (and many formats) to PDF via LaTeX,
wkhtmltopdf, or Chromium.
- Puppeteer - Headless Chrome Node.js API by Google. Extremely popular for generating PDFs from web pages.
- Playwright - Microsoft's cross-browser automation library which supports high-quality PDF generation in Chromium.
- html-pdf-node - A simple HTML to PDF converter using Puppeteer.
- jsPDF - A library to generate PDFs in client-side JavaScript. (Can render some HTML using
html2canvas).
- WeasyPrint - The awesome visual rendering engine for HTML and CSS that can export to PDF.
- pdfkit - Python wrapper for the
wkhtmltopdfutility. - xhtml2pdf - A utility for converting HTML/CSS to PDF, written entirely in Python.
- Playwright for Python - Python version of the Playwright testing and automation library.
- Dompdf - An HTML to PDF converter written in PHP. Mostly CSS 2.1 compliant.
- Browsershot - Converts HTML to an image or PDF using a headless Chrome (Puppeteer).
- Snappy - A PHP library allowing thumbnail, snapshot or PDF generation from a URL or an HTML page (wrapper for
wkhtmltopdf). - mPDF - A PHP class which generates PDF files from UTF-8 encoded HTML.
- TCPDF - One of the oldest PHP libraries for generating PDF documents, supports basic HTML.
- Wicked PDF - A PDF generation plugin for Ruby on Rails, wrapping
wkhtmltopdf. - PDFKit - A Ruby wrapper for
wkhtmltopdf. - Grover - A Ruby gem that uses Puppeteer and Chromium to transform HTML into PDFs.
- HexaPDF - A versatile PDF creation and manipulation library for Ruby.
- chromedp - A faster, simpler way to drive browsers supporting the Chrome DevTools Protocol, used for creating PDFs.
- go-wkhtmltopdf - Golang command-line wrapper for
wkhtmltopdf.
- OpenHTMLToPDF - A pure-Java library for rendering HTML/CSS-formatted documents to PDF.
- Flying Saucer - XML/CSS renderer, which can be used to convert XHTML/CSS to PDF.
- iText - Commercial library (with open-source editions) that includes an HTML to PDF add-on (
pdfHTML).
- PuppeteerSharp - .NET port of the official Node.js Puppeteer API.
- DinkToPdf - C# wrapper for
wkhtmltopdflibrary that uses Webkit engine. - SelectPdf - Provides a free community edition HTML to PDF converter for .NET.
- headless_chrome - A high-level API to control headless Chrome or Chromium over the DevTools Protocol. Can be used for printing to PDF.
- wkhtmltopdf-rs - Rust bindings for the
wkhtmltopdfC bindings.
Convert raw HTML back into clean Markdown. Most of these also ship a CLI.
- Turndown - The most popular HTML→Markdown converter for Node.js and the browser; pluggable rules (GFM via
turndown-plugin-gfm). - node-html-markdown - Fast, spec-compliant HTML→Markdown for Node.js with custom per-tag translators.
- mdream - Zero-dependency, LLM-optimized, streaming HTML→Markdown (pure JS + Rust/WASM engine); up to 2x fewer tokens than Turndown.
- h2m-parser - Fast HTML→Markdown parser with Mozilla Readability extraction and a streaming renderer.
- html-to-markdown (Kreuzberg) - High-performance, CommonMark-compliant converter powered by a shared Rust core (Node.js NAPI bindings).
- html2text - Mature Python HTML→text/Markdown converter.
- markdownify - Convert HTML to Markdown in Python with a clean API.
- html-to-markdown (Kreuzberg) - Python wheel powered by the shared Rust core (byte-identical output across runtimes).
- inscriptis - HTML to formatted text/Markdown with nested-table and list support.
- trafilatura - Web-page extraction (main text + metadata) with Markdown output.
- pyhtml2md - Python bindings for the fast C++
html2mdlibrary.
- thephpleague/html-to-markdown - The PHP League's battle-tested HTML→Markdown converter.
- goldziher/html-to-markdown (Kreuzberg) - Native PHP extension (Rust/ext-php-rs) backed by the shared engine.
- reverse_markdown - Ruby gem to convert HTML into Markdown.
- html-to-markdown (Kreuzberg) - Ruby gem powered by the shared Rust core.
- JohannesKaufmann/html-to-markdown - Robust Go converter; streaming via
io.Readerand custom HTML rules. - gohtml2md - Golang HTML→Markdown converter with template support.
- flexmark-java - Java Markdown parser/wiki engine that can emit Markdown from parsed HTML.
- html-to-markdown (Kreuzberg) - Maven Central artifact backed by the Rust core.
- ReverseMarkdown - .NET library to convert HTML to Markdown.
- KreuzbergDev.HtmlToMarkdown - NuGet package backed by the shared Rust core.
- html2md - Convert HTML to Markdown in Rust.
- htmd - HTML to Markdown converter in Rust.
- html-to-markdown-rs (Kreuzberg) - The Rust crate behind the shared engine.
- mdream (Rust) - Native Rust HTML→Markdown engine with a CLI.
- html_to_markdown (Elixir) - Elixir bindings for the Kreuzberg engine.
- h2m (Dart) - Dart/Flutter bindings for the Kreuzberg engine.
- htmltomarkdown (R) - R package for the Kreuzberg engine.
- Kreuzberg Kotlin/Android - Maven Central artifact for Android/JVM.
- Pandoc -
pandoc input.html -f html -t markdownconverts HTML to Markdown. - html-to-markdown-cli (Kreuzberg) - Fast standalone CLI (
cargo install html-to-markdown-cli).
Markdown-specific converters (most render Markdown → HTML → PDF, or parse Markdown directly). The per-language HTML→PDF libraries above (Puppeteer, WeasyPrint, etc.) also apply since they sit one step upstream.
- md-to-pdf - Hackable Node.js CLI/API using Puppeteer; custom CSS, headers/footers, page sizes.
- mdpdf - Simple Markdown → PDF for Node.
- md-bookify - CLI + MCP server; Markdown → PDF/EPUB with Prism highlighting, KaTeX math, and GFM.
- @speajus/markdown-to-pdf - TypeScript library built on marked + PDFKit; Mermaid diagrams, images, syntax highlighting.
- mdpdf-core - Pure-JS Markdown → print-ready PDF (pdf-lib/pdfkit); no Chromium, with outlines, footnotes, and pagination.
- md-preview-pdf - High-fidelity Markdown → PDF via Puppeteer; Mermaid, KaTeX, 150+ languages, multiple themes.
- remark-pdf - remark plugin compiling Markdown → PDF/A using pdfkit (no Chromium; works in browser/Node).
- markdown-pdf (alanshaw) - Node module rendering Markdown to PDF. (Note: relies on deprecated PhantomJS; often non-functional.)
- inkmd - Pure-Python Markdown → PDF compiler, zero dependencies, deterministic, no browser required.
- WeasyPrint + Markdown - Render Markdown (via
markdown/mistune) to HTML, then to PDF with print-CSS (see Python section). - xhtml2pdf - Pure-Python HTML/CSS → PDF usable from Markdown via a renderer.
- Pandoc -
pandoc input.md -o out.pdfvia LaTeX, WeasyPrint, wkhtmltopdf, pagedjs, or Chromium. - Marp - Markdown presentation ecosystem; exports slides to PDF.
- grip - Renders GitHub-flavored Markdown; pair with Print-to-PDF for faithful GitHub-style output.
- marked + Chromium -
marked→ HTML → headless Chromium--print-to-pdf.
Ready-to-use Docker images, online SaaS APIs, and web editors for PDF generation.
- SaaS APIs:
- Online Editors:
- Docker & Self-Hosted:
- Gotenberg - A Docker-powered stateless API for PDF generation. Uses Chromium and LibreOffice under the hood. Very popular for microservice architectures.
- Browserless - A cloud or self-hosted service for running headless Chrome workloads, including heavy PDF generation.
- OpenHTMLToPDF - Pure-Java (works on the JVM), so it can be used directly from Kotlin and Scala.
- Flying Saucer - XML/CSS renderer that runs on the JVM and exports XHTML/CSS to PDF.
- Playwright for Java - Official Java binding for Playwright; usable from Kotlin and Scala for Chromium-based PDFs.
- chromic_pdf - Convert HTML to PDF using headless Chromium, with a clean Elixir API and live browser management.
- pdf_generator - Wrapper around
wkhtmltopdffor generating PDFs from HTML in Elixir.
- html_to_pdf - Flutter/Dart package that renders HTML to PDF using a WebView.
- printing - Flutter plugin for printing and generating PDF documents (can render widgets/HTML to PDF).
- pagedown - R package by RStudio to render HTML and R Markdown into PDF via headless Chrome (paged.js).
- webshot - Capture screenshots (and PDFs) of web pages from R, backed by headless Chrome.
- PDF::WebKit - Perl wrapper around
wkhtmltopdffor HTML to PDF generation. - WKHTMLTOPDF - Simple Perl interface to the
wkhtmltopdfcommand-line tool.
- wkhtmltopdf (libwkhtmltox) - The C++ library and
libwkhtmltoxC API behind thewkhtmltopdfCLI tool; embeddable directly in C/C++ apps. - litehtml - Lightweight HTML/CSS rendering engine in C++ (pair it with a container like
litebrowser/wkhtmltoxto produce PDFs).
JavaScript/CSS libraries that bring print-layout features (paged media, running headers, page breaks) to any HTML pipeline:
- Paged.js - A free, open-source polyfill that implements the W3C Paged Media and Generated Content specs in the browser; ideal for books and reports.
- Vivliostyle - Open-source CSS Typesetting engine supporting EPUB/Web publications and paginated HTML to PDF.
- CJK - A collection of print-CSS examples and a
print-css.rocksengine for high-quality print output.
The formats and specs that HTML-to-PDF tooling implements or targets:
- PDF 2.0 (ISO 32000-2) - The current PDF specification; most modern engines aim for 2.0 compatibility.
- PDF/A - The ISO standard for long-term archival of electronic documents (no external dependencies, embedded fonts).
- PDF/UA - PDF for Universal Accessibility (ISO 14289), important for accessible/section-508 output.
- PDF/X - PDF for graphic arts / print-ready exchange (ISO 15930).
- W3C Paged Media Module - CSS spec for paged output:
@page, margins, page size, and page selectors. - W3C CSS Fragmentation - Controls how content breaks across pages/columns (
break-before,break-inside). - HTML & CSS Print - Print-specific CSS features that drive pagination and print media.
Building blocks that operate directly on the PDF format (create, inspect, or manipulate PDFs) rather than rendering HTML:
- libharu - Free C/C++ library for generating PDF files from scratch.
- PDFium - Google's open-source PDF rendering engine (C++), embedded in Chromium; also usable for headless PDF output.
- MuPDF - Lightweight C library and
mutoolCLI for rendering, converting, and editing PDFs. - qpdf - C++ library and CLI to inspect, transform, and linearize/optimize PDFs (great for post-processing output).
- Apache PDFBox - Pure-Java library to create, render, and manipulate PDF documents.
- iText Core - The core low-level library for Java and .NET (C#) to build and manipulate PDFs.
- pikepdf - Python library (binding for QPDF) for reading, writing, and transforming PDFs.
- borb - Pure-Python PDF library for creating and editing PDFs with a clean, document-object API.
- ReportLab - A robust, time-tested Python library for generating PDFs and graphics.
- Prawn - A fast, nimble PDF generation library for Ruby.
- gofpdf - A PDF document generator with high level support for text, drawing and images in Go.
- FPDI / FPDF - PHP classes for generating and manipulating PDFs without external dependencies.
- PDFKit - Pure-JS library for server-side PDF generation in Node.js (programmatic, not HTML-based).
Here is a high-level comparison of the most common engines powering these tools:
| Engine / Tool | Underlying Tech | Modern CSS/JS Support | Setup Complexity | Best For |
|---|---|---|---|---|
| Puppeteer / Playwright | Headless Chromium | Excellent | Medium | Complex SPAs, modern UI, charts |
| wkhtmltopdf | Qt WebKit (Old) | Poor (No Flexbox/Grid) | Low | Legacy systems, simple layouts |
| WeasyPrint | Native Python | Good (No JS) | Low | Python-centric setups, print media |
| PrinceXML | Proprietary | Excellent (No JS) | Medium | High-end print publishing, commercial |
| Dompdf / mPDF | Native PHP | Moderate (No JS) | Low | Shared hosting, simple PHP generation |
Which approach is available in which language. ✅ = mature option, ◐ = possible but limited, ➖ = not applicable / uncommon.
| Language | Headless Browser | Native Engine | wkhtmltopdf Wrapper | Notable Picks |
|---|---|---|---|---|
| Node.js / JS | ✅ Puppeteer, Playwright | ◐ jsPDF | ✅ | Puppeteer, Playwright |
| Python | ✅ Playwright | ✅ WeasyPrint, xhtml2pdf | ✅ pdfkit | WeasyPrint, Playwright |
| PHP | ✅ Browsershot | ✅ Dompdf, mPDF, TCPDF | ✅ Snappy | Browsershot, Dompdf |
| Ruby | ✅ Grover | ✅ HexaPDF | ✅ Wicked PDF, PDFKit | Grover, Wicked PDF |
| Go | ✅ chromedp | ➖ | ✅ go-wkhtmltopdf | chromedp |
| Java | ✅ Playwright Java | ✅ OpenHTMLToPDF, Flying Saucer | ➖ | OpenHTMLToPDF |
| C# / .NET | ✅ PuppeteerSharp | ◐ SelectPdf | ✅ DinkToPdf | PuppeteerSharp |
| Rust | ✅ headless_chrome | ➖ | ✅ wkhtmltopdf-rs | headless_chrome |
| Kotlin / Scala | ✅ Playwright Java | ✅ OpenHTMLToPDF, Flying Saucer | ➖ | OpenHTMLToPDF |
| Elixir | ✅ chromic_pdf | ➖ | ✅ pdf_generator | chromic_pdf |
| Dart | ◐ WebView-based | ◐ printing | ➖ | html_to_pdf |
| R | ✅ pagedown, webshot | ➖ | ➖ | pagedown |
| Perl | ➖ | ➖ | ✅ PDF::WebKit | PDF::WebKit |
| C / C++ | ◐ embed Chromium | ◐ litehtml | ✅ libwkhtmltox | libwkhtmltox |
Takeaways:
- Every mainstream language has at least one headless-browser or wkhtmltopdf path.
- True native HTML/CSS engines are concentrated in Python, PHP, Ruby, and the JVM.
- For pixel-perfect, JS-heavy output, headless Chromium (Puppeteer/Playwright/chromedp/Grover/chromic_pdf) is the universal answer across languages.
When choosing a library from the lists above, it's helpful to understand the trade-offs of the underlying approaches.
- Pros: Perfect rendering identical to a real browser. Supports all modern CSS (Flexbox, Grid) and executes JavaScript perfectly. Ideal for charts, web fonts, and Single Page Applications (SPAs).
- Cons: High resource consumption (memory/CPU). Slower generation time. Can be tricky to deploy in serverless environments (e.g., AWS Lambda, Vercel) due to large browser binary sizes.
- Pros: Easy to install via standard package managers. Lightweight compared to headless browsers. Very fast for simple, text-heavy documents. No external system dependencies or binaries required.
- Cons: Often struggle with modern CSS layout modules. Most do not support executing JavaScript, meaning client-side rendered elements (like JS charts or React/Vue apps) will not render.
- Pros: Historically the standard across all languages. Very easy to use if the binary is already installed on your server.
- Cons: Uses an extremely outdated rendering engine. It lacks support for modern CSS features and ES6+ JavaScript. It is officially deprecated and unmaintained.
- Pros: Purpose-built for print layout — excellent support for
@page, page breaks, headers/footers, tables spanning pages, and book-level typography. No browser binary needed. - Cons: No JavaScript execution. Requires authoring your HTML/CSS with print media in mind rather than screen design. Best suited to documents, reports, and books rather than web-app screenshots.
- Pros: Zero infrastructure — no browser binaries or system dependencies to maintain. Scales automatically, handles complex JS, and typically offers templating, storage, and webhooks. Great for serverless or high-throughput setups.
- Cons: Recurring cost and vendor lock-in. Data leaves your infrastructure (privacy/compliance consideration). Network latency and rate limits apply.
Contributions are very welcome! Please feel free to open a pull request if you have a great library to add.
To the extent possible under law, the contributors have waived all copyright and related or neighboring rights to this work.
