Turning HTML into a polished PDF, stamping and merging documents, or digitally signing contracts are everyday needs in PHP projects. The “best” library depends on your use case—HTML fidelity, performance, PDF/A compliance, digital signatures, RTL text, cost, and deployment constraints. This guide reviews the most-used options—dompdf, mPDF, TCPDF, FPDF, HTML2PDF, PDFlib, SetaPDF—and adds modern alternatives that use a real browser engine (wkhtmltopdf, Browsershot/Chrome headless) plus FPDI for importing/editing existing PDFs. You’ll also find clear recommendations by scenario, code snippets, and production checklists.


TL;DR — what to pick and when

  • Standard invoices/reports from HTML:
    mPDF or dompdf. mPDF is strong with long documents, tables, and RTL; dompdf wins on ease of use and a huge community.
  • Pixel-perfect layouts with advanced CSS (flex, some grid), webfonts, complex SVG:
    wkhtmltopdf (with a PHP wrapper) or Browsershot (Chrome headless). These render like a real browser. Requires installing external binaries.
  • Draw-from-code, high performance, no HTML:
    TCPDF (open source) or PDFlib (commercial) for speed and fine-grained control.
  • Digital signatures, PDF/A, forms, redaction, splitting/merging at scale:
    SetaPDF (commercial, modular) or TCPDF for basic signing.
  • Import pages from existing PDFs and stamp/number/watermark:
    FPDI (with FPDF/TCPDF/mPDF).

CSS Grid/Flex support is partial or absent in PHP HTML renderers. For pixel fidelity, use a browser engine (wkhtmltopdf/Chrome headless).


Expanded comparison table

Versions and minimum PHP requirements vary; check each library’s composer.json for your target version.
“HTML support” means how well it turns modern HTML/CSS into accurate layout.

LibraryOpen SourceHTML-basedOOPInstall via ComposerDocsKey DependenciesLicenseHTML/CSS SupportRTL / Complex scriptsPDF/A / SigningImages / SVGTypical Use
dompdfYesYesYesYesGoodPHP 7/8, ext-dom, ext-mbstring, php-font-lib, php-svg-libMITCSS 2.1 + parts of CSS3; HTML5 partialDecentNo native PDF/A / no signingSVG basicEasy start, popular for invoices/reports
mPDFYesYesYesYesGoodPHP 7/8, ext-mbstring, ext-gdGPLCSS 2.1 + partial HTML5; strong tablesVery goodPDF/A-1b/2b profiles; basic signingImages + partial SVGLong docs, RTL, enterprise invoicing
TCPDFYesPartial (HTML light)YesYesFairPHP 7/8LGPLBasic HTML (limited CSS)GoodDigital signatures, barcodes, QRImages + SVGHigh speed drawing, precise control
FPDFYesNoYesNo (manual)FairVery light, no extensionsLGPLN/ANo (extensions needed)JPG/PNGMinimal PDFs coded by hand
HTML2PDF (spipu)YesYesYesYesGoodPHP ≥ 5.6, ext-gd, ext-mbstring (uses TCPDF)LGPLParser + TCPDF backendPartialDepends on TCPDFImagesSimple pipeline; less active than mPDF/dompdf
PDFlibNoNoYesNoExcellentPDFlib extension/SDKCommercialDraw API (no HTML)Advanced features incl. signingHighFastest & feature-rich, but paid
SetaPDF (Setasign)NoNoYesYesExcellentComposer modulesCommercialNo HTML renderingPDF/A, signing, forms, redactionHighBest-in-class PDF manipulation suite
wkhtmltopdf (PHP wrappers)Bin. externalYes (WebKit)Yes (wrapper)Goodwkhtmltopdf binaryLGPL (bin), wrappers MITNear-browser fidelityYesDependsExcellentPixel-perfect print of web pages
Browsershot (Chrome)WrapperYes (Chromium)YesGoodNode.js + Chrome/ChromiumMITFull modern CSS (like Chrome)YesDependsExcellentHighest fidelity; requires Node/Chrome
FPDICore is OSSNoYesYesGoodNeeds FPDF/TCPDF/mPDFMIT (+ add-ons)N/ANo (core)Import/compose existing PDFs

Strengths and trade-offs by approach

A) Pure PHP HTML→PDF (dompdf, mPDF, HTML2PDF)

  • Pros: easy deployment (no external binaries), good for invoices/reports, friendly with frameworks (Laravel/Symfony), predictable performance.
  • Cons: incomplete support for modern CSS (grid/flex), some SVG/webfont quirks, edge cases with complex responsive layouts.

Pick mPDF when you need strong table handling, RTL, and basic PDF/A profiles. Pick dompdf for simplest onboarding and a huge community.

B) Real browser engines (wkhtmltopdf, Browsershot/Chrome headless)

  • Pros: highest layout fidelity (what you see in a browser is what you get), excellent webfont/SVG support, advanced CSS.
  • Cons: you must install binaries (wkhtmltopdf or Chrome), consider memory/timeouts, and harden execution for security.

Great for catalogs, brochures, marketing layouts, and any “pixel-perfect” design.

C) Code-driven drawing (TCPDF, FPDF, PDFlib)

  • Pros: speed, deterministic output, millimetric control, no HTML conversion; supports barcodes, bookmarks, signatures.
  • Cons: more development time for layout, less flexible for last-minute design changes.

TCPDF is the open-source workhorse; PDFlib is the fastest/most comprehensive commercial toolkit.

D) Manipulation, signing, and assembly (SetaPDF, FPDI)

  • SetaPDF covers enterprise-grade needs: PDF/A, advanced digital signatures, form fields, redaction, repair, split/merge.
  • FPDI is perfect for importing existing PDFs (official templates) and stamping on top with FPDF/TCPDF/mPDF.

Concrete recommendations by scenario

  • Invoices, purchase orders, administrative PDFs (logos, tables, totals):
    mPDF (tables/RTL/PDF-A) or dompdf (simplicity). If design fidelity is critical, wkhtmltopdf.
  • Long narrative reports (pagination, TOC, headers/footers):
    mPDF; TCPDF if you don’t need complex HTML/CSS.
  • Compliance: PDF/A archiving, digital signatures, forms:
    SetaPDF (best coverage) or TCPDF for basic signatures; PDFlib if performance/commercial support is a must.
  • Stamping official templates (import existing PDF, add text/seals/page numbers):
    FPDI + FPDF/TCPDF/mPDF.
  • Pixel-perfect catalogs/marketing layouts mirroring the website:
    Browsershot (Chrome) or wkhtmltopdf.

Minimal usage examples

dompdf (simple HTML→PDF):

use Dompdf\Dompdf;

require 'vendor/autoload.php';

$html = '<h1>Invoice #2025-001</h1><p>Total: €1.245,50</p>';

$dompdf = new Dompdf([
    'isRemoteEnabled' => true,
    'defaultFont'     => 'DejaVu Sans',
]);
$dompdf->loadHtml($html, 'UTF-8');
$dompdf->setPaper('A4', 'portrait');
$dompdf->render();
$dompdf->stream('invoice-2025-001.pdf', ['Attachment' => true]);
Code language: PHP (php)

mPDF (tables, RTL, PDF/A profile):

$mpdf = new \Mpdf\Mpdf(['mode' => 'utf-8', 'format' => 'A4']);
$mpdf->PDFA = true;               // enable PDF/A mode
$mpdf->PDFAauto = true;
$mpdf->WriteHTML('<style>table{border-collapse:collapse}td,th{border:1px solid #ccc;padding:6px}</style>');
$mpdf->WriteHTML('<table><tr><th>Item</th><th>Amount</th></tr><tr><td>Service</td><td>€1.245,50</td></tr></table>');
$mpdf->Output('report.pdf', 'I');
Code language: HTML, XML (xml)

TCPDF (draw from code):

$pdf = new TCPDF();
$pdf->AddPage();
$pdf->SetFont('dejavusans','',12);
$pdf->Cell(0,10,'Monthly Report',0,1);
$pdf->Output('report.pdf','I');
Code language: PHP (php)

wkhtmltopdf (PHP wrapper):

use mikehaertl\wkhtmlto\Pdf;

$pdf = new Pdf('<h1>Catalog</h1><p>Rendered by WebKit</p>');
$pdf->binary = '/usr/local/bin/wkhtmltopdf';
$pdf->setOptions(['enable-local-file-access' => true]);
if (!$pdf->send('catalog.pdf')) {
    error_log($pdf->getError());
}
Code language: PHP (php)

FPDI (import an existing PDF and stamp text):

use setasign\Fpdi\Fpdi;

$pdf = new FPDI();
$pageCount = $pdf->setSourceFile('template.pdf');
for ($i = 1; $i <= $pageCount; $i++) {
    $tplIdx = $pdf->importPage($i);
    $pdf->AddPage();
    $pdf->useTemplate($tplIdx);
    $pdf->SetFont('Helvetica','',10);
    $pdf->Text(20, 280, 'Stamped: '.date('Y-m-d'));
}
$pdf->Output('stamped.pdf', 'I');
Code language: PHP (php)

Original checklist (expanded)

LibraryOpen SourceHTML-basedOOPComposerDocsDependencies
dompdfYesYesYesYesGoodPHP 7/8; ext-dom, ext-mbstring, php-font-lib, php-svg-lib
FPDFYesNoYesNoFairNone (very light)
HTML2PDFYesYesYesYesGoodPHP ≥ 5.6; ext-gd, ext-mbstring (TCPDF backend)
mPDFYesYesYesYesGoodext-mbstring, ext-gd; PHP 7/8
TCPDFYesNo (HTML lite)YesYesFairPHP 7/8
PDFlibNoNoYesNoExcellentPDFlib SDK (commercial)
SetaPDFNoNoYesYesExcellentComposer modules (commercial)

Recommended additions:

LibraryOpen SourceHTML-basedOOPComposerDocsDependencies
wkhtmltopdf (wrapper)Wrapper OSSYes (WebKit)YesGoodwkhtmltopdf binary
Browsershot (Spatie)YesYes (Chrome)YesGoodNode.js + Chrome/Chromium
FPDICore OSSNoYesYesGoodWorks with FPDF/TCPDF/mPDF

Production best practices

  1. Fonts & Unicode: ship DejaVu/Noto; subset fonts to shrink files.
  2. Images: optimize; use JPG for photos, PNG/SVG for graphics; cap at 300 dpi for print.
  3. Pagination: test long tables and multipage content; tune CSS (page-break-*).
  4. Resources & timeouts: set sensible memory_limit and time limits; HTML rendering can be heavy.
  5. Deterministic builds: embed fonts/CSS (no remote CDN) for legal/archival documents.
  6. Visual regression tests: keep “golden” PDFs and compare in CI to catch renderer version drift.
  7. Security: never render untrusted HTML without sanitization; sandbox external binaries.

Conclusion

  • For reliable HTML→PDF with strong tables and RTL, mPDF is the most balanced generalist.
  • For simplicity and community, dompdf is an excellent default.
  • For pixel-perfect results, go with wkhtmltopdf or Browsershot (accepting the binary/Node requirement).
  • For enterprise-grade manipulation (PDF/A, signing, forms, redaction), choose SetaPDF (or PDFlib if you want raw performance and can license it).
  • For template stamping and assembling existing PDFs, FPDI is the right tool.
  • For absolute control and speed without HTML, TCPDF or PDFlib (draw-API) are hard to beat.

The “best” library is the one that minimizes your maintenance cost for the job at hand. Balance fidelity, performance, compliance features, and operational constraints (binaries, hosting, CI/CD) before committing.

Scroll to Top