Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Short answer: choose a pure-PHP renderer when deployment simplicity, predictable PDF structure or PHP-only hosting matters; choose Chromium through Browsershot or Gotenberg when modern CSS fidelity matters most. Dompdf is the practical choice for CSS 2.1-level invoices and letters, mPDF is strong for UTF-8, print controls and right-to-left text, and tc-lib-pdf is the current pure-PHP option when PDF/UA structure, signatures and conformance controls are priorities.

The architectural decision comes first

PHP HTML-to-PDF tools fall into two distinct classes. A pure-PHP/layout engine parses HTML and CSS inside your PHP process. A browser-backed wrapper delegates rendering to Chromium, QtWebKit or a separate conversion service. The second class can reproduce a modern web page more faithfully, but it introduces another runtime to install, patch, monitor and version.

No library is universally fastest. Rendering time and memory depend on document complexity, fonts, images, PHP extensions, browser version and runtime configuration. Test representative documents rather than relying on a generic benchmark.

Pure-PHP engines

Dompdf, mPDF and tc-lib-pdf run without a browser process. They are easier to deploy on PHP-only hosting and can make output more reproducible because there is no external browser binary changing underneath the application. Their CSS support is intentionally narrower than a current browser, so layouts that depend on modern web features may need a print-specific template.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Browser-backed conversion

Browsershot 5.4 (MIT) starts Chromium through Node and Puppeteer. Gotenberg PHP 2.25 (MIT) calls a Gotenberg HTTP service that runs Chromium and LibreOffice. Snappy 1.7 (MIT) starts the wkhtmltopdf binary. These wrappers are useful when your source is already a modern web page, but the engine or service must be installed, patched and kept available. Browser updates can also change line breaks, pagination and other pixels, so pin and test the engine version used in production.

Comparison at a glance

The package versions below were checked on 2026-08-31; versions and requirements can change, so verify them before starting a new project.

Option Rendering model Where it fits Important strengths Trade-offs
Dompdf Pure PHP; mostly CSS 2.1 Invoices, letters and straightforward reports External stylesheets, media and page rules, table row and column spans, common raster images; bundled R&OS CPDF avoids an external PDF library Modern CSS is outside its core target; PDFLib is optional and changes the performance/memory trade-off
mPDF Pure PHP, designed for UTF-8 HTML Print-oriented business documents Color handling, pre-print, barcodes, headers, footers, page numbering, tables of contents and right-to-left text Still uses its own HTML/CSS renderer rather than a full browser
tc-lib-pdf Pure PHP; defined HTML/CSS subset Controlled, deterministic generation with conformance requirements PHP 8.2+, Composer packages, PDF/UA structure, signatures and conformance controls Subset rendering will not match every modern browser layout
Browsershot 5.4 Chromium via Node and Puppeteer Modern web pages and CSS-heavy templates Browser layout fidelity Node/Chromium installation, patching and version management; output can change after engine updates
Gotenberg PHP 2.25 HTTP call to Gotenberg running Chromium and LibreOffice Teams that prefer a separate conversion service Moves browser and office runtimes out of the PHP application process A service must be deployed, secured, monitored and kept compatible
Snappy 1.7 / wkhtmltopdf QtWebKit binary Existing deployments tied to its historical output Established command-line workflow and MIT PHP wrapper QtWebKit predates much of CSS3; wkhtmltopdf was archived upstream in January 2023, so it is a compatibility path rather than the default for new work

Dompdf: the simplest PHP-only starting point

Dompdf describes its core as a mostly CSS 2.1-compliant HTML layout and rendering engine written in PHP. It handles external stylesheets, media and page rules, table row and column spans, and common raster image formats. Its bundled R&OS CPDF class removes the need for an external PDF library. PDFLib is optional; the project states that PDFLib improves performance and reduces memory requirements somewhat, while R&OS CPDF is slightly slower but dependency-free.

That profile makes Dompdf a good fit for invoices, letters and reports whose layout can be expressed with conventional print CSS. Do not select it solely because the source page looks good in a browser: validate flexbox, grid, advanced positioning and other modern constructs in the actual PDF.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Minimal PHP example

After installing Dompdf through Composer, render a fresh instance for each document. The project warns against reusing one instance for multiple HTML documents because parsing and rendering artifacts can persist.

<?php
require __DIR__ . '/vendor/autoload.php';

use DompdfDompdf;
use DompdfOptions;

$options = new Options();
$options->set('isRemoteEnabled', true);
$dompdf = new Dompdf($options);

$html = '<!doctype html>
<html><head>
<meta charset="utf-8">
<style>@page { margin: 20mm; } body { font-family: sans-serif; }</style>
</head><body>
<h1>Invoice</h1><p>Generated from HTML.</p>
</body></html>';

$dompdf->loadHtml($html, 'UTF-8');
$dompdf->setPaper('A4', 'portrait');
$dompdf->render();
$dompdf->stream('invoice.pdf', ['Attachment' => false]);

Remote assets add another dependency and another failure point. For reproducible output, prefer local, versioned stylesheets and images, and make sure the PHP process can read every font and image your template references.

mPDF: print controls, UTF-8 and RTL documents

mPDF is designed to generate PDFs from UTF-8-encoded HTML. Its documented focus is print production: color handling, pre-print, barcodes, headers and footers, page numbering, tables of contents and right-to-left text. Choose it when those features matter more than reproducing a browser’s complete CSS implementation.

Minimal PHP example

<?php
require __DIR__ . '/vendor/autoload.php';

$mpdf = new MpdfMpdf([
    'format' => 'A4',
    'orientation' => 'P',
    'margin_left' => 20,
    'margin_right' => 20,
    'margin_top' => 20,
    'margin_bottom' => 20,
]);

$html = '<meta charset="utf-8">
<h1>שלום / تقرير</h1>
<p>UTF-8 text, headers and page numbering can be added to this print template.</p>';
$mpdf->WriteHTML($html);
$mpdf->Output('report.pdf', MpdfOutputDestination::INLINE);

Keep the HTML deliberately print-oriented. A browser page may rely on layout behavior that mPDF does not implement, while a document designed around explicit widths, page breaks, headers and footers is easier to maintain.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

tc-lib-pdf: structure, signatures and conformance controls

tc-lib-pdf is documented as the current generation of TCPDF. It is a pure-PHP option for PHP 8.2 and later, installed through Composer and split into focused packages. Its HTML renderer handles a defined subset of HTML and CSS directly, with no browser engine.

The reason to choose it is control rather than browser fidelity. In PDF/UA mode, headings are mapped into a structure tree, text is tagged, figure alternative text becomes /Alt, and form fields receive /TU descriptions. The project also documents PDF signature profiles and other conformance controls. Confirm the exact package and API version during installation because package boundaries and requirements are not permanent.

When Chromium is the better renderer

If the input is a modern web page and visual fidelity is the dominant requirement, use a Chromium-backed path such as Browsershot or Gotenberg. You gain the browser’s CSS and layout behavior, but you must operate Node, Chromium or a conversion service. Plan for sandboxing, process limits, font installation, health checks and controlled upgrades. A browser update can legitimately alter pagination, so keep golden PDFs for representative pages and review changes before rollout.

Direct PDF conformance, signatures, spot colors and page-box controls are limited in browser-backed workflows or require a second PDF tool. If those requirements are contractual, evaluate tc-lib-pdf or a post-processing stage instead of assuming that accurate pixels imply accessible or signed PDF output.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How to choose for a real project

  1. List the document requirements. Record paper size, margins, repeating headers, page numbering, tables, barcodes, RTL scripts, signatures, PDF/UA, encryption and whether the source uses modern CSS.
  2. Choose the rendering boundary. Stay pure PHP when an external runtime is unacceptable. Use Chromium when browser fidelity outweighs operational simplicity.
  3. Match the pure-PHP engine. Pick Dompdf for conventional CSS 2.1 layouts, mPDF for UTF-8-heavy print documents and RTL or barcode features, and tc-lib-pdf for structure, signatures and conformance controls.
  4. Prototype with production content. Include long tables, missing images, unusual Unicode, the largest expected font set and the longest realistic report. Check page breaks rather than only the first page.
  5. Freeze what must be reproducible. Pin PHP dependencies and, for browser-backed tools, the Node, Chromium or service version. Store a small set of approved PDFs for regression comparison.
  6. Measure your workload. Capture wall time, peak memory, queue behavior and failure rates on your own documents. The available descriptions do not establish a universal speed winner.

Pagination, fonts and output quality checklist

  • Set page size, orientation and margins explicitly instead of inheriting browser defaults.
  • Use print-specific CSS and deliberate page breaks for invoices, statements and long tables.
  • Verify every required font, image and stylesheet is readable by the rendering process in production.
  • Test UTF-8 text, accented characters, CJK text and RTL scripts with the actual fonts you will ship.
  • Inspect headings, alternative text and form-field descriptions when accessibility or PDF/UA is required.
  • Check signatures, page boxes and other conformance controls separately from visual fidelity.
  • Generate each Dompdf document with a new instance; do not carry parser state into the next request or job.

Troubleshooting common failures

Modern CSS is missing or rearranged

Cause: the selected pure-PHP engine supports a narrower CSS subset than a browser. Fix: simplify the print stylesheet, replace unsupported layout constructs with explicit widths and page rules, or move the job to Chromium.

Blank or partially rendered images

Cause: the renderer cannot read a remote or protected asset. Fix: make assets locally available to the process, verify permissions and URLs, and test the same request from the production worker rather than from your laptop.

Broken accents or RTL text

Cause: the HTML is not treated as UTF-8 or the required font is unavailable. Fix: declare UTF-8, use a font covering the script, and choose mPDF when RTL and print-oriented text handling are central requirements.

Memory exhaustion on long reports

Cause: large images, many pages, complex tables or renderer-specific buffering. Fix: reduce image dimensions, split very large jobs, measure peak memory and test PDFLib with Dompdf if its external dependency is acceptable.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

PDFs change after deployment

Cause: a browser, font, PHP package or conversion service changed. Fix: pin versions, retain representative reference PDFs and review intentional upgrades before production.

One request works but a batch fails

Cause: state leakage, resource limits or a single bad document. Fix: create a fresh renderer per document, isolate failures by job, record the input identifier and retry only failures after correcting the cause.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your goal is to capture a rendered URL rather than maintain a local Chromium stack, ScreenshotNeo is a hosted website screenshot API and MCP server. It can return PNG, JPEG, WebP or PDF from one GET request. Before capture it accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups and chat widgets; each step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing status.

The same service supports full-page captures with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets plus custom viewports, retina scale, PDF paper size and margins, custom CSS and JavaScript, click-before-capture, waits, request and resource blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, configurable caching, signed links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API and an OpenAPI specification. An MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

See the ScreenshotNeo API documentation for PDF options and the complete parameter list. The following request is runnable as written and saves a WebP response:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' }); const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

The Free plan includes 1,000 shots each month with no card. Paid plans start at $5 for 3,000 shots; every feature is on every plan, and yearly billing provides two months free. Create a free ScreenshotNeo account to try it.

Bottom line

Start with Dompdf when a CSS 2.1-level, PHP-only document is enough. Choose mPDF for UTF-8, RTL and print-production features. Choose tc-lib-pdf when PDF/UA structure, signatures or conformance controls are more important than complete browser CSS. Use Chromium through Browsershot or Gotenberg when modern CSS fidelity is the deciding factor, and keep wkhtmltopdf for existing QtWebKit-compatible deployments rather than new designs.

Frequently Asked Questions

Can I switch from a pure-PHP renderer to Chromium later?

Yes, but treat it as a rendering change rather than a drop-in upgrade. Keep a print-specific template and compare representative PDFs because pagination, line wrapping and page breaks can change when the layout engine changes.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Does visual similarity guarantee an accessible PDF?

No. Browser fidelity and PDF structure are separate concerns. If tagging, alternative text, form descriptions or PDF/UA conformance matter, select a tool and workflow that explicitly provides those controls, such as tc-lib-pdf in PDF/UA mode.

Should wkhtmltopdf be used for a new application?

Only when compatibility with an existing QtWebKit-rendered output is a deliberate requirement. Its upstream project was archived in January 2023 and its engine predates much of CSS3, so validate every required layout feature.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.