By PDFKits Team — Published February 19, 2026
TL;DR. Converting HTML to PDF means deciding where rendering happens. Browser print-to-PDF (Ctrl+P → Save as PDF) is fine for one-off saves. Headless Chrome (via Puppeteer or Playwright) is the right approach for production pipelines that generate invoices, reports, or shipping labels — it renders modern CSS, web fonts, and dynamic content faithfully because it IS Chrome. Server-side libraries (WeasyPrint, wkhtmltopdf, PDFKit-JS) trade CSS support for predictability. For ad-hoc conversion of a web page or saved HTML file, browser-only tools like PDFKits handle the file without uploading anything. The right pick is the one whose CSS support matches your HTML's complexity.
HTML-to-PDF is one of those problems that looks trivial and turns out to depend on what you're trying to do. The first decision is rendering engine: full-featured Chromium (handles modern CSS, web fonts, flexbox, grid, JavaScript-rendered content) or a lighter renderer (faster, more predictable, but with quirks around CSS support). The second is where it runs: in a browser (interactive, single document at a time), in a headless process (batch-capable, scriptable, repeatable), or in a fully isolated library (no Chromium dependency, deployable on minimal servers).
Each path has a typical user profile. Marketing and ops teams generating receipts, reports, and shipping labels lean headless-Chrome because the input HTML is complex and the output needs to look pixel-perfect. Developers shipping documents from a constrained backend (Lambda, container) lean WeasyPrint or wkhtmltopdf because the binary footprint matters. Knowledge workers saving a single web page lean browser print-to-PDF because it requires zero setup.
Priya runs the billing operations for a 50-person SaaS company. Customer invoices are generated from an HTML template populated with order data, then rendered to PDF for emailing. The team uses Puppeteer in a Node.js service: each invoice request returns an HTML page from the billing API, headless Chrome renders it, and the PDF goes to the customer's email and the accounting archive. The setup handles 2,000+ invoices per month with no human in the loop.
Daniel manages landing pages for a B2C startup. Each A/B test variant needs a PDF snapshot for the experiment archive — the visual baseline that the test was run against. Browser print-to-PDF works for the occasional one-off, but for the team's standard process they use a small Playwright script that takes a URL, waits for the page to fully load (including web fonts and lazy-loaded images), and saves the result. Snapshots go into the experiment results doc.
Carlos works at a fulfillment center that produces 800–1,200 shipping labels daily. The carrier API returns label HTML; the system converts to PDF for the warehouse's thermal printers. wkhtmltopdf is the tool of choice — fast, predictable for the simple, repetitive label HTML, and runs inside the existing Linux infrastructure without a Chromium dependency.
Amara archives source material as PDFs — articles, government press releases, social media posts she wants to cite. Browser print-to-PDF, sometimes combined with reader-mode in Firefox or Chrome, is the right tool: one click, looks fine, no upload, no third-party service. For pages with paywalls or complex rendering, she uses PDFKits' tools to clean up the resulting PDF afterward.
Marcus assembles trial exhibits including snapshots of websites at specific points in time. The print-to-PDF output is filed as Exhibit B-12, with the URL and timestamp visible in the page footer (browser settings). For more rigorous archival (e.g., to file as evidence under hearsay exceptions for business records), the team uses a screenshot-plus-metadata workflow rather than a "save as PDF" — but for routine exhibits, browser print is enough.
Open the Create PDF tool. Paste a URL or upload an HTML file. Choose page size (A4, US Letter, fit-to-content), orientation, and margins. Optionally toggle header/footer with the URL and date. Click Create. PDFKits renders the HTML in your browser, produces the PDF, and offers it for download. The file is built locally — useful for HTML files that contain client information you don't want to upload to a third-party converter.
For HTML that depends on JavaScript-rendered content, the tool fetches the page after JS execution where possible. For pages behind authentication or paywalls, save the rendered HTML locally first (right-click → Save Page As) and upload the saved HTML — the conversion will use whatever is in the saved file.
Best for: one-off saves, journalists, knowledge workers, casual archiving.
Strengths: zero setup, identical to what you see on screen, supports all CSS and fonts that the browser supports.
Weaknesses: cannot automate, page breaks can be awkward, header/footer customization is limited to what the browser exposes.
Best for: production pipelines, complex HTML, modern CSS, dynamic content.
Strengths: pixel-perfect parity with Chrome, full CSS and JavaScript support, scriptable batches.
Weaknesses: heavy binary (Chromium is ~150 MB), slower per-document than lighter tools, requires Chrome execution environment.
Best for: high-volume simple HTML (labels, receipts, basic reports).
Strengths: fast, lightweight, runs in any environment with Qt.
Weaknesses: WebKit-based renderer is years behind Chrome — modern CSS features (CSS Grid in particular) often fail. Project is in maintenance mode; for new builds, prefer headless Chrome.
Best for: server-side document generation in Python, when CSS Paged Media is needed.
Strengths: pure Python, no Chromium, excellent support for CSS Paged Media (page numbers, headers, footers, named pages).
Weaknesses: limited JavaScript support, slower than wkhtmltopdf for simple HTML.
Best for: programmatic PDF generation where you control the layout in code.
Strengths: client-side, no HTML rendering — you draw the PDF directly. Small footprint.
Weaknesses: not actually an HTML-to-PDF tool — you write code to position text and images, which is not what you want if you have existing HTML.
| Feature | PDFKits | Puppeteer (DIY) | Smallpdf | Adobe Acrobat Online |
|---|---|---|---|---|
| Cost | Free | Free (run yourself) | $108/year | $29.99/month |
| Files stay on your device | Yes | Yes (your server) | No — cloud | No — cloud |
| Modern CSS (Grid, custom fonts) | Yes (browser-based) | Yes (Chrome) | Yes | Yes |
| Batch / scriptable | No (UI only) | Yes | Limited | Limited |
| Per-page header/footer control | Basic | Full (Puppeteer API) | Limited | Yes |
| Save authenticated pages | Yes (via local file) | Yes (script the auth) | Limited | Limited |
| No installation | Yes | No (Node + Chromium) | Yes | Yes |
For an individual saving a single page, PDFKits or browser print are both fine and identical in privacy. For a production pipeline shipping thousands of documents per day, Puppeteer or a similar headless setup is the only viable option — neither online tool nor manual print scales.
Background colors and images. Most browser print dialogs default to "no background graphics" to save ink. If your HTML uses colored backgrounds for headers or callouts, enable "Background graphics" in the print options or pass printBackground: true to Puppeteer.
Web fonts that don't load before render. Headless Chrome can start rendering before web fonts finish loading. The fix is page.evaluateHandle('document.fonts.ready') in Puppeteer, or in browser print, wait for the page to fully load (visible delay of 1–2 seconds) before invoking Save as PDF.
Page break control. Use page-break-before: always, page-break-after: avoid, and page-break-inside: avoid (or the newer break-* properties) to control where pagination occurs. Without these, a chart or table may be split mid-row.
Fixed vs absolute positioning. position: fixed elements behave inconsistently across renderers — sometimes the element repeats on every page, sometimes it appears only on page one. Test with multi-page content before deploying.
Media queries. Use @media print to define print-specific styles — hide navigation, expand collapsed content, switch to print-friendly fonts. Many web pages look much better in PDF after adding a 20-line print stylesheet.
Three usual suspects: print-only CSS (the page has @media print rules), missing background colors (print dialog stripped them), or web fonts that hadn't loaded when the snapshot was taken. Check the page's stylesheet for @media print rules, and verify fonts are loaded before converting.
Yes, but you have to be logged in at the time of conversion. Browser print works directly. For programmatic conversion, the script needs to handle authentication — log in to capture session cookies, then pass them to the headless browser before navigating to the page.
Browser print typically captures only what's visible. For infinite-scroll pages, scroll to the bottom first (manually or via a script that triggers all scrolling) before invoking print. Some sites have a "view as article" or "single-page view" mode that bypasses the issue.
It depends on the input HTML. If the HTML has proper semantic tags (headings, alt text on images, ARIA labels), the resulting PDF usually inherits the structure as tags. Untagged HTML produces untagged PDF. For full PDF/UA compliance, post-process with Adobe Acrobat Pro.
In Puppeteer: pass displayHeaderFooter: true with templated HTML for header and footer. In browser print: the dialog has options for header and footer text. For full control, use CSS Paged Media @page rules with WeasyPrint.
Yes, if the fonts are loaded at conversion time. Web fonts referenced via @font-face in the page's CSS are embedded into the PDF by headless Chrome and by browser print. Local fonts available on the user's system are also embedded.
For a typical content page with text and a few images, expect 200 KB to 2 MB. Pages with many high-resolution images can exceed 10 MB. Run Optimize PDF on the result to bring file size down to web-shareable levels.
Not from a UI tool — that's where Puppeteer scripts shine. A short Node.js script can iterate URLs, convert each, and save with a sensible filename. Plan on 1–3 seconds per page on average hardware.
Use the page's reader mode (Firefox, Edge, Chrome with extensions) to strip chrome before saving. Or in a script, scrape the article container only and convert that fragment. Both approaches avoid carrying ads and navigation into the PDF.
SVG renders cleanly through Chrome-based converters (Puppeteer, browser print). wkhtmltopdf and some older tools rasterize SVG, producing blurry output. If SVG fidelity matters, use a Chrome-based converter.
Create PDF (HTML to PDF) — Convert URLs and HTML files in the browser. Merge PDF — Combine converted pages with other PDFs. Optimize PDF — Shrink large converted PDFs for sharing. Edit PDF — Post-conversion edits to the PDF output. Clean Metadata — Strip URL and creator info before sharing. Page Numbers — Add consistent page numbers to multi-page exports.