How to convert HTML to PDF: 10 best tools compared
Table of contents
Nutrient DWS handles rendering, fonts, and CSS for you - start with 50 free credits.
For HTML with JavaScript, start with Puppeteer or Playwright’s Chromium PDF export. For Python print layouts, evaluate WeasyPrint; for PHP templates, consider Dompdf. jsPDF and html2pdf.js support browser exports, while pdfmake and PDFKit build documents from code rather than render HTML. Nutrient Document Engine provides a commercial conversion API with additional PDF operations. Compare output using your actual pages, fonts, forms, and page-break requirements.
The best HTML-to-PDF converter depends on what you start with and what the PDF must preserve. A JavaScript application, a static invoice template, and a downloadable screenshot need different rendering approaches.
This guide compares 10 tools by input type, rendering approach, and practical limitations. It includes open source and commercial options; the order isn’t a performance ranking. Nutrient publishes this comparison and offers one of the products listed.
Comparison: Best tools to convert HTML to PDF
Use this table to shortlist tools before testing their output. Form creation, digital signing, encryption, and standards validation are separate capabilities, not part of a basic HTML conversion call.
| Tool | Best starting point | Main consideration |
|---|---|---|
| Nutrient Document Engine | HTML templates in a commercial PDF processing workflow | Requires a service deployment and the relevant licensed components |
| wkhtmltopdf | Existing integrations with tested legacy templates | Archived project using an older Qt WebKit engine |
| Puppeteer | JavaScript-rendered webpages in Node.js | Manage the browser process and wait for application content |
| Playwright | Chromium PDF export in an existing automation setup | Browser automation is cross-browser; PDF export uses Chromium |
| jsPDF | Browser PDF generation with text, drawing, or HTML helpers | Choose the rendering method carefully; screenshots produce image-based output |
| html2pdf.js | Downloading a webpage section as an image-based PDF | Text isn’t selectable or searchable in its rasterized output |
| WeasyPrint | Python HTML/CSS templates for paginated documents | Doesn’t execute page JavaScript |
| pdfmake | Documents defined with JavaScript objects | Doesn’t render an existing HTML/CSS page directly |
| PDFKit | Programmatic PDF creation with drawing and text APIs | Doesn’t parse HTML/CSS |
| Dompdf | Static HTML templates in PHP applications | Doesn’t support CSS flexbox or grid |
1. Convert HTML to PDF with Nutrient Document Engine
Nutrient Document Engine accepts HTML through a REST API and can apply additional PDF operations in the same processing workflow. It’s useful when your workflow combines document generation with merging, watermarking, form handling, or other PDF features.
The HTML-to-PDF guide explains the source format and layout options. With Document Engine running at http://localhost:5000, save your HTML as page.html, replace the API token placeholder, and run:
curl --fail-with-body --request POST http://localhost:5000/api/build \ --header "Authorization: Token token=<API token>" \ --form 'page.html=@page.html' \ --form 'instructions={"parts":[{"html":"page.html"}]}' \ --output result.pdfThis request uploads an HTML file and identifies it in the parts array. For external stylesheets, images, and fonts, follow the guide’s asset packaging rules. Previewing a template in Chrome can help with layout, but test the generated PDF because pagination and supported features can differ.
Document Engine supports fillable PDF forms through configured HTML form elements. Signatures, encryption, and other operations require their own configuration and licensed components. The conversion request above doesn’t include them.
The tradeoff is a commercial dependency and a service to configure and operate, unless you choose a managed deployment. Weigh those costs against the development and maintenance work your team would otherwise take on.
Start a free trial or talk to Sales to test the required components with your documents.
2. Convert HTML to PDF using wkhtmltopdf

wkhtmltopdf(opens in a new tab) converts HTML using Qt WebKit. Its command-line options cover page size, margins, headers, and footers, and it can execute JavaScript supported by that older engine.
The project was archived in January 2023(opens in a new tab). Existing templates may still work, but don’t expect support for modern browser CSS and JavaScript. For a new integration, evaluate a maintained alternative before adopting it.
Its command-line reference(opens in a new tab) includes an --enable-forms option for PDF form support. Support varies by control type and PDF reader, so test both.
For existing integrations, see our Python and C# tutorials.
3. Convert HTML to PDF using Puppeteer

Puppeteer(opens in a new tab) automates Chrome and Firefox. The example below uses its default Chrome setup to render a webpage and print it to PDF. It suits pages whose content depends on browser JavaScript and CSS.
Install puppeteer with npm, save this as convert.cjs, and run it with node convert.cjs:
const puppeteer = require('puppeteer');
async function convert() { const browser = await puppeteer.launch(); try { const page = await browser.newPage(); await page.goto('https://example.com', { waitUntil: 'load' }); await page.waitForSelector('h1'); await page.evaluate(() => document.fonts.ready); await page.pdf({ path: 'output.pdf', format: 'A4', printBackground: true, }); } finally { await browser.close(); }}
convert().catch((error) => { console.error(error); process.exitCode = 1;});The h1 selector is a readiness check for this example page. For your application, wait for the specific content or state that confirms its data has rendered. A network-idle event can fire before a chart or an asynchronous task finishes.
You’ll need to manage browser installation, concurrent jobs, timeouts, and access to assets. The exported PDF is a static document, not an interactive copy of the web application.
4. Convert HTML to PDF using Playwright

Playwright(opens in a new tab) automates Chromium, Firefox, and WebKit, but its page.pdf()(opens in a new tab) export is supported in headless Chromium. Reach for it when your team already uses Playwright for browser automation.
Install playwright with npm and run npx playwright install chromium. Save this example as convert.cjs and run it with node convert.cjs:
const { chromium } = require('playwright');
async function convert() { const browser = await chromium.launch(); try { const page = await browser.newPage(); await page.goto('https://example.com', { waitUntil: 'load' }); await page.locator('h1').waitFor(); await page.evaluate(() => document.fonts.ready); await page.pdf({ path: 'output.pdf', format: 'A4', printBackground: true, margin: { top: '1cm', bottom: '1cm' }, }); } finally { await browser.close(); }}
convert().catch((error) => { console.error(error); process.exitCode = 1;});As with Puppeteer, replace the example URL and readiness condition with your application’s requirements. Test pagination and content in the PDF itself; a browser screenshot test won’t catch problems in the printed output. Our JavaScript HTML-to-PDF tutorial covers related approaches.
5. Convert HTML to PDF using jsPDF

jsPDF(opens in a new tab) creates PDFs with text, images, and drawing APIs. Its HTML helper relies on additional dependencies, including html2canvas. The PDF’s contents depend on the API you use: jsPDF can create text or embed a screenshot of a page.
For a small browser export where an image-based PDF is acceptable, the following function captures a single HTML element. It requires jspdf and html2canvas in a browser project with a bundler:
import { jsPDF } from 'jspdf';import html2canvas from 'html2canvas';
export async function downloadPdf(element) { if (!element) { throw new Error('Provide an HTML element to export.'); } await document.fonts.ready; const canvas = await html2canvas(element); const pdf = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'a4' }); const margin = 10; const maxWidth = pdf.internal.pageSize.getWidth() - 2 * margin; const maxHeight = pdf.internal.pageSize.getHeight() - 2 * margin; const scale = Math.min(maxWidth / canvas.width, maxHeight / canvas.height); pdf.addImage( canvas.toDataURL('image/png'), 'PNG', margin, margin, canvas.width * scale, canvas.height * scale, ); pdf.save('output.pdf');}Call downloadPdf() with a visible element after its images and data have loaded, and handle a rejected promise in your application. The example scales the entire capture onto one page, so a long element can become too small to read. Its text is rasterized; choose another method if you need selectable text or proper multipage layout.
For framework examples, see our React, Vue.js, and Angular tutorials.
6. Convert HTML to PDF using html2pdf.js

html2pdf.js(opens in a new tab) combines html2canvas and jsPDF into a browser export workflow. It captures rendered HTML as an image and places that image into PDF pages.
This works for downloading a visual copy of a webpage section when searchable text isn’t required. The project documents limitations involving rendering differences, element cloning, reflow, and maximum canvas dimensions. Test long pages and page breaks, because a successful export can still crop content or divide it awkwardly.
Captured HTML inputs become part of that image, not fillable PDF fields. See our html2pdf.js tutorial or React example for setup details.
7. Convert HTML to PDF using WeasyPrint

WeasyPrint(opens in a new tab) is an HTML/CSS rendering engine designed for paginated documents. It fits Python applications that generate reports, letters, or invoices from templates, particularly when print styling matters more than reproducing a browser application.
It doesn’t execute JavaScript. Render application data into the HTML before conversion, and check the CSS features your template needs. Installation also requires platform dependencies such as Pango.
After following the installation instructions, a Python script can convert a local file:
from weasyprint import HTML
HTML(filename='page.html').write_pdf('output.pdf')WeasyPrint supports fillable PDF forms(opens in a new tab) through its pdf_forms option. It also offers PDF variants for specialized output, but still validate the resulting document against your requirements.
For a longer example, see generating PDF reports from HTML in Python.
8. Convert HTML to PDF using pdfmake

pdfmake(opens in a new tab) builds PDFs from a document definition object containing text, tables, images, styles, and layout instructions. It runs in Node.js and browsers.
Choose it when your source is application data and you’re willing to define the document layout in JavaScript. It doesn’t directly render an existing HTML page or its CSS. Adapters that translate HTML into a document definition support their own subset of markup; they aren’t a replacement for a browser rendering engine.
9. Convert HTML to PDF using PDFKit
PDFKit(opens in a new tab) creates PDFs using text and drawing APIs. It provides fonts, images, vector graphics, encryption, and interactive form APIs(opens in a new tab).
It suits applications that need control over a generated document’s structure and layout. Like pdfmake, it’s an alternative to HTML-based generation: It doesn’t parse HTML and CSS for you; you’ll write layout logic and test pagination yourself.
10. Convert HTML to PDF using Dompdf

Dompdf(opens in a new tab) converts HTML and CSS in PHP applications. It supports most CSS 2.1 properties and some CSS 3 features, which covers static templates in an existing PHP stack.
It doesn’t run webpage JavaScript or support flexbox and grid. Its documentation also notes pagination limitations for table cells. Design and test a print template around those constraints; an arbitrary web application page won’t convert cleanly.
How to choose the right tool to convert HTML to PDF
Start with the source and output requirements. Then compare the work needed to operate each option.
Match the renderer to the source
For a page that depends on JavaScript, use a browser renderer or prerender its content. For static templates, evaluate WeasyPrint or Dompdf in your existing language stack. If the source is structured data and you don’t need HTML, pdfmake or PDFKit may be simpler than maintaining a separate HTML template.
Check text, forms, and accessibility separately
Decide whether users need to select text, search the document, complete form fields, or use a screen reader. An image-based export can look correct while failing those requirements. Fillable form support also varies by control type and configuration; both WeasyPrint(opens in a new tab) and Nutrient Document Engine document HTML-to-PDF form workflows.
If you need PDF/A or PDF/UA, validate the generated files against the required profile. A tool that produces a PDF may not produce a conforming one.
Compare operational costs with representative jobs
Test conversion time, peak memory, page count, and output size with your own documents. Include long tables, custom fonts, images, and concurrent jobs.
Open source tools can support production workflows, but your team owns integration and operations. A commercial SDK or API adds licensing costs and can provide supported PDF features. Compare the complete workflow, including maintenance and deployment. Neither license model guarantees better output.
Best practices for HTML-to-PDF conversion
A consistent print template and a representative test set matter, regardless of which renderer you choose.
Use print-specific CSS
For a renderer that honors print media, hide navigation and set page dimensions explicitly:
@page { size: A4; margin: 2cm;}
@media print { nav, .no-print { display: none; } body { margin: 0; font-size: 12pt; } h2 { break-after: avoid; } figure { break-inside: avoid; }}Defaults and supported CSS differ between tools. In Puppeteer and Playwright, use preferCSSPageSize: true if you want a CSS @page size to take priority over the API’s paper size. A canvas screenshot workflow captures the screen layout, not the print layout.
Wait for content and assets
Wait for the application’s data, charts, fonts, and images before printing. Use an explicit readiness signal for dynamic content. A page can remain busy with background requests after its content is ready, or finish network requests before a chart has rendered.
Test pagination and image quality
Inspect the first, middle, and final pages of long documents. Check that headers, tables, and images aren’t clipped and that page-break rules work in the selected renderer. An element taller than a page will break somewhere.
Choose image dimensions based on their printed size and required quality. One resolution setting rarely suits every document, so measure file size and legibility.
Conclusion
Choose a renderer that fits your source content. Then verify the PDF features your users need. Puppeteer and Playwright handle browser-rendered pages; WeasyPrint and Dompdf suit supported HTML templates; jsPDF and html2pdf.js offer browser exports. pdfmake and PDFKit are options when you can define documents from data.
If you need HTML conversion alongside additional PDF operations through a supported API, evaluate Nutrient Document Engine with a free trial, or talk to our Sales team.
FAQ
It depends on the content. Evaluate Puppeteer or Playwright for JavaScript-rendered pages, WeasyPrint for Python print templates, and Dompdf for supported PHP templates. Test the same sample documents before choosing.
Yes, with a tool and configuration that support it. WeasyPrint has a pdf_forms option, and Nutrient Document Engine documents HTML form conversion. wkhtmltopdf also exposes an --enable-forms option, although its project is archived. A screenshot-based export doesn’t create fillable fields.
No. Playwright automates those browsers, but its PDF export uses headless Chromium. Cross-browser automation support and PDF generation support are separate capabilities.
That depends on the rendering method. html2pdf.js and the jsPDF screenshot example in this article embed images, so their text isn’t selectable. Use a text-preserving renderer when search, copying, or text extraction is required, and test the generated output.
Some PDF processing tools support those operations, but they require explicit configuration. Check the signing workflow, certificate requirements, encryption options, and licensing separately from basic HTML conversion.
Related posts
- How to convert HTML to PDF in JavaScript
- How to convert HTML to PDF in React
- How to convert HTML to PDF using Python and wkhtmltopdf
- How to convert HTML to PDF in C# using wkhtmltopdf
- How to convert HTML to PDF using html2pdf
- Generate a PDF from HTML with Vue.js
- Top HTML-to-PDF conversion tools
- Six best PDF generator APIs compared
- HTML in PDF format: Five conversion methods