Choose the renderer that matches your HTML. Use Dompdf when a mostly CSS 2.1 document must run in PHP without another process; choose mPDF for UTF-8-heavy, print-oriented documents and RTL text; choose tc-lib-pdf when deterministic pure-PHP output, PDF/UA structure, signatures, or conformance controls matter; and use Chromium through Browsershot or a service such as Gotenberg when reproducing a modern web page is the priority. wkhtmltopdf is chiefly a legacy-compatibility choice because its QtWebKit engine predates much of CSS3 and its upstream project was archived in January 2023.
Start with the architectural choice
PHP HTML-to-PDF tools fall into two groups:
- Pure-PHP/layout engines: PHP parses HTML and CSS and writes the PDF itself. Deployment is simpler and output can be easier to make deterministic, but browser-era CSS is usually unsupported or only partially supported.
- Browser-backed wrappers or services: PHP starts Chromium, QtWebKit, or an HTTP conversion service. CSS fidelity is closer to what users see in a browser, but you must install, patch, monitor, and version another runtime.
No library is universally best. Decide first whether your acceptance test is “the invoice prints correctly with controlled CSS” or “this existing responsive web page must look like Chrome.” Then evaluate pagination, Unicode and RTL text, accessibility, signing, deployment, memory, and reproducibility.
How the main options compare
| Option | Architecture | HTML/CSS behavior | Print, accessibility, and PDF controls | Operational profile | Best fit |
|---|---|---|---|---|---|
| Dompdf | Pure PHP; bundled R&OS CPDF, optional PDFLib | Mostly CSS 2.1; external stylesheets, media and page rules, tables with spans, common raster images | Conventional reports and page rules; no browser-level CSS fidelity | No external PDF library is required. PDFLib can improve performance and reduce memory use | Invoices, letters, and reports with restrained CSS |
| mPDF | Pure PHP | Designed for UTF-8 encoded HTML with print-focused behavior | Color handling, pre-print, barcodes, headers and footers, page numbering, tables of contents, and RTL text | PHP-only deployment; tune fonts, temporary storage, and memory for large jobs | Multilingual and print-heavy documents |
| tc-lib-pdf | Pure PHP; current TCPDF generation | Defined subset of HTML and CSS rendered without a browser | PDF/UA structure, tagged text, figure alternate text, form-field descriptions, signatures, and conformance controls | PHP 8.2 or later; Composer packages are split by responsibility | Deterministic output, accessibility, signing, and detailed PDF controls |
| Browsershot 5.4 | PHP wrapper that launches Chromium through Node and Puppeteer | Modern browser CSS and JavaScript | Excellent visual fidelity; direct PDF conformance and signing may require another tool | Install and patch Node, Puppeteer, and Chromium; engine updates can alter output | Web pages that depend on modern CSS or client-side rendering |
| Gotenberg PHP 2.25 | PHP client for a Gotenberg HTTP service using Chromium and LibreOffice | Modern browser rendering through a separate service | Useful service boundary, but browser-backed conformance and signing remain limited | Operate, secure, and version the Gotenberg service | Teams that want conversion isolated from the PHP application |
| Snappy 1.7 / wkhtmltopdf | PHP wrapper around a QtWebKit binary | Older CSS engine; much of CSS3 is unavailable | Predictable for an existing deployment, but not a modern browser equivalent | Requires a binary. wkhtmltopdf upstream was archived in January 2023 | Maintaining a known legacy rendering result |
Package versions and PHP requirements change. The versions above were checked on 2026-08-31; verify current Composer constraints and runtime requirements before locking a new deployment.
Dompdf: the simplest PHP-only path
Dompdf describes its core as a mostly CSS 2.1-compliant HTML layout and rendering engine written in PHP. It supports 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 when lower memory use or better performance is worth an additional dependency.
Recommended Free Tools
#1 Best Overall
Install and render a document
composer require dompdf/dompdf
<?php
require __DIR__ . '/vendor/autoload.php';
use DompdfDompdf;
use DompdfOptions;
$options = new Options();
$options->setIsRemoteEnabled(true); // Enable only when you trust the URLs in the HTML.
$dompdf = new Dompdf($options);
$html = '<!doctype html>
<html><head><meta charset="utf-8">
<style>@page { margin: 18mm; } body { font-family: DejaVu Sans, sans-serif; }</style>
</head><body><h1>Invoice</h1><p>Generated at ' . htmlspecialchars(date('c'), ENT_QUOTES, 'UTF-8') . '</p></body></html>';
$dompdf->loadHtml($html, 'UTF-8');
$dompdf->setPaper('A4', 'portrait');
$dompdf->render();
$dompdf->stream('invoice.pdf', ['Attachment' => false]);
Keep remote loading disabled unless needed, whitelist assets when possible, and embed or reliably serve fonts. Create a new Dompdf instance for each document: the project warns that parsing and rendering artifacts can persist if one instance is reused.
mPDF: print features, UTF-8, and RTL scripts
mPDF is designed to generate PDFs from UTF-8 encoded HTML. It is a strong choice when pagination and print controls are more important than reproducing a full browser layout. Its documented feature set includes color handling, pre-print, barcodes, headers and footers, page numbering, tables of contents, and right-to-left text.
Basic mPDF example
composer require mpdf/mpdf
<?php
require __DIR__ . '/vendor/autoload.php';
$mpdf = new MpdfMpdf([
'format' => 'A4',
'tempDir' => __DIR__ . '/var/mpdf'
]);
$mpdf->SetTitle('Statement');
$mpdf->SetHTMLHeader('<div style="text-align:right">Statement</div>');
$mpdf->SetHTMLFooter('<div style="text-align:center">Page {PAGENO} of {nbpg}</div>');
$mpdf->WriteHTML('<h1>Statement</h1><p dir="rtl">مرحبا بالعالم</p>');
$mpdf->Output(__DIR__ . '/statement.pdf', MpdfOutputDestination::FILE);
Use a writable temporary directory, register fonts appropriate for every script you emit, and test page breaks with the longest realistic tables. Large images and unbounded table rows can dominate memory regardless of the library.
Rank #2
- LIGHTWEIGHT AND FOLDABLE STRUCTURE: Foldable design (30x6x8cm) and lightweight (1000g) make it portable for travel or home use. Compact shape fits perfectly on your workbench without taking up much space
- SIMPLE CONNECTION: Works with USB connection without the need for additional programs for quick installation. Simple controls make it easy to operate both beginners and regular users with regular size papers
- QUICK DOCUMENT PROCESSING: Automatically scan suggestions one page per second, greatly increase productivity. Ideal for workplaces, schools, legal/financial areas where large capacity is required
- TEXT CONVERSION TECHNOLOGY: Smart OCR function works in over 200 languages, changes scanned files to editable text for easy storage and editing Seamless digital conversion of paper documents improves workflow
- EXCELLENT IMAGEING: Equipped with a 16MP clear camera, this portable document scanner produces crisp, accurate images of documents and keeps important content intact. Perfect for striking scans of contracts, receipts and books
tc-lib-pdf: structure, signatures, and conformance
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 as focused packages. Its HTML renderer handles a defined HTML/CSS subset directly, without a browser engine. That trade-off is deliberate: you give up full browser CSS in exchange for direct PDF controls.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Its documented PDF/UA mode maps headings into a structure tree, tags text, maps figure alternate text to /Alt, and gives form fields /TU descriptions. It also documents signature profiles and other conformance controls. Choose it when an accessibility or signing requirement is a release criterion, not merely a visual preference. Validate the generated file with the accessibility and signature tools required by your jurisdiction or customer.
When Chromium is the right renderer
Use Browsershot/Chromium or a similar browser-backed path when the source uses modern layout, web fonts, JavaScript, flexbox, grid, or client-side data hydration that a pure-PHP engine cannot reproduce. Browsershot 5.4 launches Chromium through Node and Puppeteer. Gotenberg PHP 2.25 sends jobs to a Gotenberg service running Chromium and LibreOffice.
Minimal Browsershot workflow
composer require spatie/browsershot
npm install puppeteer
<?php
require __DIR__ . '/vendor/autoload.php';
use SpatieBrowsershotBrowsershot;
Browsershot::url('https://example.com/report')
->showBackground()
->format('A4')
->savePdf(__DIR__ . '/report.pdf');
Pin Node, Puppeteer, and Chromium versions in deployment, install required system fonts, and record the browser version with each release. A browser update can change line wrapping, pagination, font fallback, and generated metadata. Run visual regression tests against representative documents after upgrades. If your application cannot run a browser process, put Gotenberg behind an authenticated internal endpoint and monitor its queue, disk, and process limits.
Pagination, fonts, and security checks
Pagination
- Define page size and margins explicitly instead of relying on browser defaults.
- Exercise headings at the bottom of a page, long table rows, nested lists, and images that are taller than the remaining space.
- For invoices, test the largest customer name, address, tax description, and line-item count you accept.
Fonts and Unicode
Use UTF-8 consistently from the database through the template and response headers. A missing glyph usually indicates a font or embedding problem, not an HTML encoding problem. Test accented Latin, CJK, Arabic, and emoji separately; a fallback font may alter line widths and therefore page breaks.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Security
- Sanitize user-provided HTML and never allow arbitrary PHP or JavaScript in templates.
- Restrict remote URL loading and file access. Otherwise a converter may be abused to fetch internal services or local files.
- Apply timeouts, memory limits, maximum HTML size, and image-size limits to untrusted jobs.
- For browser-backed conversion, run Chromium with a least-privilege account and isolate the conversion service from application credentials.
Performance, reliability, and cost decisions
There is no universal speed or memory winner. Results depend on document complexity, fonts, images, PHP extensions, browser version, and runtime configuration. Benchmark your own representative set: a short invoice, a long table, a multilingual document, and the largest image-heavy report you support.
- Pure PHP: fewer moving parts and easier horizontal scaling, but complex layouts can consume substantial PHP memory.
- Chromium: better modern-CSS fidelity, with startup cost and an additional process to supervise. Reuse a controlled worker or service only if its isolation and lifecycle are well understood.
- Determinism: pin package, font, and engine versions; freeze timestamps and asset URLs in regression fixtures; compare page count, text extraction, and rendered images.
- Failure handling: treat missing fonts, timeouts, broken remote assets, and malformed HTML as distinct errors so retries do not hide a template defect.
Or skip the browser setup
If your input is an accessible URL and you need a clean capture rather than a PHP layout engine, ScreenshotNeo provides a website screenshot API and MCP server. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. The API can return PNG, JPEG, WebP, or PDF; see the ScreenshotNeo documentation for the PDF and capture options.
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}`);
ScreenshotNeo also offers an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. Every feature is on every plan: 1,000 shots per month are free with no card, and paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account to try it.
Troubleshooting by symptom
CSS looks correct in Chrome but not in the PDF
You are probably using a pure-PHP engine outside its supported CSS subset. Replace unsupported layout with print CSS, or move this document to Chromium. Do not assume adding more HTML will make a CSS 2.1 renderer implement grid or browser JavaScript.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsImages or stylesheets are missing
Check absolute URLs, certificate validity, authentication headers, and the converter’s remote-resource setting. For production, prefer local or signed assets and log every failed resource request.
Best Value
Text is replaced by squares
Install and register a font containing the missing glyphs, confirm UTF-8 declarations, and verify that the font is actually embedded in the PDF. Browser and pure-PHP renderers may choose different fallback fonts.
Pages shift after an upgrade
Pin Composer packages, fonts, Node/Puppeteer/Chromium, and system image versions. Re-run visual fixtures and inspect line wrapping before promoting the upgrade.
The process times out or runs out of memory
Reduce image dimensions, stream or paginate large datasets, set explicit job limits, and inspect the generated HTML size. For Chromium, also check process counts and shared-memory limits; for PHP engines, check the worker memory limit and temporary-directory capacity.
A practical selection checklist
- Choose Dompdf for straightforward documents when CSS 2.1-level layout and a PHP-only deployment are sufficient.
- Choose mPDF for UTF-8-heavy output, RTL scripts, barcodes, headers, footers, and print pagination.
- Choose tc-lib-pdf when PDF/UA structure, signatures, or deterministic pure-PHP controls outweigh browser CSS fidelity.
- Choose Browsershot/Chromium or Gotenberg when the source is a modern web page and visual fidelity is the dominant requirement.
- Choose Snappy/wkhtmltopdf only to preserve a known QtWebKit deployment, after validating every required CSS feature.
Frequently Asked Questions
How should I test a converter before committing to it?
Create a fixture set containing a long table, page-break rules, remote and local images, multilingual text, RTL content, and your largest realistic document. Compare page count, extracted text, key metadata, and rendered page images on every dependency upgrade.
Can one application use more than one renderer?
Yes. A common design is a pure-PHP renderer for controlled transactional PDFs and Chromium for web-page captures. Keep templates and acceptance tests separate so a renderer change does not silently alter the other document class.
What should be treated as a breaking change?
Any change to fonts, CSS support, browser or Qt engine versions, page size defaults, image handling, or PDF tagging can change pagination or compliance. Treat those upgrades like application releases and review generated fixtures.
Quick Recap
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.

