dompdf alternatives in 2026: modern CSS, real browsers, and what works on shared hosting
The best dompdf alternative depends on one question most comparisons skip: can you install things on your server? If you can only run PHP, your realistic moves are another pure-PHP library (mpdf, TCPDF), which shares dompdf's CSS ceiling, or an HTTP API like Transformy, which needs no install at all and renders with a real browser. If you control the server, Browsershot and Gotenberg bring headless Chrome to your own infrastructure.
dompdf deserves a fair description: actively maintained, pure PHP, one composer require away. That zero-install property is why it is everywhere, and it is also the root of every reason people search for alternatives: a PDF renderer written entirely in PHP cannot be a browser.
$ php artisan pdf:render invoice-1042
WARN css: display:flex not supported (block fallback)
WARN Image not found or type unknown: logo.svg
PHP Fatal error: Allowed memory size of 134217728
bytes exhausted in vendor/dompdf/…/Renderer.php
layout engine ········ CSS 2.1-era
javascript ··········· not supported (by design)
$
KEY TAKEAWAYS
- dompdf's ceiling is CSS 2.1-era layout. No flexbox, no grid, no JavaScript; templates get built with tables and floats like it is 2009, because inside dompdf it mostly is.
- The server question decides your options. Pure-PHP libraries and HTTP APIs work anywhere PHP runs; Browsershot and Gotenberg require Node/Chrome or Docker on infrastructure you control.
- An API is the zero-install path to browser rendering. One HTTP call from any PHP host gets flexbox, grid, webfonts, and JavaScript, with nothing to install.
- mpdf and TCPDF fix different dompdf pains, not the big one. Better Unicode and stability respectively, but neither renders modern CSS or scripts.
- If you found this page via laravel-snappy: stop. Snappy wraps wkhtmltopdf, which is archived with unpatched critical CVEs; that migration is overdue.
Why PHP teams look for dompdf alternatives
Modern CSS does not render. dompdf implements roughly CSS 2.1: no flexbox, no grid, partial float behavior. Every invoice template becomes a nested-table archaeology project, and pasting in your designer's HTML produces a layout from another decade. The moment "make the PDF match the web page" is a requirement, dompdf cannot meet it.
No JavaScript, ever. Chart libraries, client-rendered components, and anything that draws after page load are invisible to dompdf. Like WeasyPrint on the Python side, this is by design and no flag changes it.
Memory and speed strain at size. A pure-PHP layout engine pays for long documents: Allowed memory size exhausted in the renderer is a rite of passage, and batch runs of large statements get slow enough to schedule around.
Assets are fussy. The classic "Image not found or type unknown" error, partial SVG support, font subsetting quirks, and remote-asset configuration flags (isRemoteEnabled and friends) make templates brittle in ways browser engines are not.
None of this is neglect. dompdf trades rendering power for universal deployability, and it holds up its end. The alternatives below are for when that trade stops paying.
Tip
If your documents are simple, table-shaped, and rendering correctly, dompdf remains a fine default. Migrate for a reason, not for fashion.
First, answer the server question
Shared hosting, managed platforms, no root
Your options are pure-PHP libraries (mpdf, TCPDF) or an HTTP API. An API is the only way to get browser rendering here, because the browser runs elsewhere.
Options: Transformy, mpdf, TCPDF
VPS, containers, your own cluster
Browsershot (Node + Chrome on the host) and Gotenberg (Docker) become available, alongside everything in case 1.
Adds: Browsershot, Gotenberg
The shortlist at a glance
| TOOL | TYPE | ENGINE | SHARED HOSTING | PRICING | BEST FOR |
|---|---|---|---|---|---|
| Transformy | Managed API | Headless Chrome | Yes (HTTP only) | Free 100 docs/mo, then $99/mo for 10,000 | Browser-grade rendering with nothing to install |
| Browsershot | PHP package (wraps Puppeteer) | Headless Chrome | No (needs Node + Chrome) | Free (your infra) | Laravel/PHP teams with their own servers |
| Gotenberg | Self-hosted service | Chromium + LibreOffice | No (needs Docker) | Free (your infra) | Service-shaped rendering inside your cluster |
| mpdf | PHP library | Own engine | Yes | Free | Pure-PHP with better Unicode and some CSS gains |
| TCPDF | PHP library | Own engine | Yes | Free | Long-lived, stable, programmatic PHP PDFs |
The managed option: Transformy
For the shared-hosting case, Transformy is the move that changes the ceiling instead of trading within it: your PHP renders the HTML exactly as it does today, then one authenticated POST returns a PDF rendered by real headless Chromium. Flexbox, grid, webfonts, SVG, and JavaScript all behave like the browser your designer tested in, and nothing gets installed on the host, because the browser is on the other end of an HTTPS call.
use Illuminate\Support\Facades\Http;
$response = Http::withToken(config('services.transformy.key'))
->post('https://api.transformy.io/v1/pdf/chrome', [
'html' => view('invoices.show', ['invoice' => $invoice])->render(),
'page_size' => 'a4',
'margin' => '2cm',
'footer' => ['html' => '<span style="font-size:10px">Page {{page}} of {{pages}}</span>'],
]);
Storage::put("invoices/{$invoice->number}.pdf", $response->body());
Beyond the rendering upgrade, the production plumbing matters at volume: async jobs with signed webhooks, delivery straight to your own S3 bucket (which replaces the Storage::put above if you prefer), idempotency keys for safe retries, and a free watermarked test mode. Pricing starts free (100 documents a month, no credit card); the Pro plan is $99/month for 10,000 documents, then $0.01 per additional document. The honest trade-offs: a per-document fee replaces a free library, rendering leaves your network boundary, and each render is a network round-trip rather than an in-process call, so batch pipelines should use the async mode rather than looping over synchronous requests.
The self-hosted routes (you control the server)
Browsershot
Spatie's Browsershot is the Laravel world's favorite bridge to real Chrome: a PHP package that shells out to Puppeteer, so Browsershot::html($html)->save('invoice.pdf') produces genuine browser output. The API is pleasant and the rendering is everything dompdf is not. The requirements are the catch: Node.js and a Chrome/Chromium install on every host that renders, which rules out shared hosting and complicates containers (your PHP image now ships a browser). You also inherit the browser-operations bill (memory, process management, Chrome upgrades) that every self-hosted Chrome setup pays; our Puppeteer alternatives page covers that territory in depth, and our Browsershot alternatives comparison weighs its options specifically.
Gotenberg
If you would rather keep browsers out of your PHP hosts entirely but inside your infrastructure, Gotenberg runs Chromium (and LibreOffice) behind an HTTP API in a Docker container. Your PHP calls it exactly the way it would call a managed API; the container and its scaling stay yours. It is a natural fit for teams already on Docker or Kubernetes, and a poor fit for anyone without that platform. We weigh its own trade-offs in our Gotenberg alternatives page.
The pure-PHP routes (no install rights needed)
mpdf
mpdf is dompdf's closest sibling and the usual first alternative PHP teams try. Its genuine advantages: substantially better Unicode and RTL support, @page handling that suits paged documents, and header/footer facilities that feel less bolted-on. Its ceiling is the same in kind: no JavaScript, no flexbox or grid, and its own set of quirks at scale. Moving dompdf templates to mpdf is real work that buys incremental gains; it is the right move when Unicode or pagination is your specific pain, and a lateral move if modern CSS is.
TCPDF
TCPDF is the elder statesman: two decades old, extremely stable, and still maintained. Its HTML support is the most limited of the three PHP libraries; where it shines is programmatic generation, drawing documents through its API (cells, multi-cells, barcodes, signatures) rather than rendering rich HTML. Teams with rigid, data-driven documents sometimes find TCPDF's explicit placement more reliable than any HTML rendering; teams with designed templates find it painful. It is also the only option here with built-in digital-signature support, which occasionally decides the whole question.
Migrating: from dompdf templates to a browser engine
Moving to any Chrome-based renderer (Transformy, Browsershot, Gotenberg alike) is less a migration than a parole hearing for your templates:
- $dompdf->loadHtml($html) / Pdf::loadView('invoices.show', $data)
+ same Blade view, rendered to a string, sent as "html"
- $dompdf->setPaper('A4', 'landscape')
+ "page_size": "a4", "orientation": "landscape"
@page { margin: 2cm }
+ keeps working ("prefer_css_page_size": true)
- table-and-float layouts built around missing flexbox
+ flexbox and grid finally render (tables still work too)
- $dompdf->getCanvas()->page_script(...) // page numbers
+ "footer": {"html": "… {{page}} of {{pages}} …"}
- isRemoteEnabled, image-type errors, SVG workarounds
+ assets load like a browser loads them (SVG, webfonts included)
- ini_set('memory_limit', '512M') // before big renders
+ not your process anymore
The pleasant surprise in most dompdf migrations is deletion: the workarounds (tables faking columns, inline base64 images, font pre-processing) exist because of the engine, and a browser engine makes them unnecessary. Budget one test pass over your real documents, watch page breaks on the longest ones, and remember header/footer fragments are isolated documents that need inline styles.
Frequently asked questions
Is dompdf still maintained?+
Yes, actively. This page exists because dompdf's design (pure PHP, no browser) caps its rendering, not because the project is at risk. For simple table-shaped documents on hosts where you can install nothing, it remains a sensible default.
Does dompdf support flexbox or grid?+
No. dompdf implements roughly CSS 2.1, so modern layout modules are ignored and templates fall back to block layout. Only browser-engine tools (Transformy, Browsershot, Gotenberg) render flexbox and grid in PDFs.
Is laravel-snappy a good dompdf alternative?+
No. Snappy wraps wkhtmltopdf, which was archived in 2023 and carries unpatched critical CVEs. Moving from dompdf to an abandoned engine is a downgrade in security for a modest gain in CSS. See our wkhtmltopdf alternatives page if you are on Snappy today.
mpdf or dompdf: which is better?+
They are siblings with different strong suits: mpdf for Unicode, RTL, and paged-document features; dompdf for ubiquity and Laravel integration. Neither runs JavaScript or modern CSS, so if that is your pain, the answer is neither.
Can I get browser-quality PDFs on shared hosting?+
Yes, via an HTTP API. The browser runs on the vendor's infrastructure, so the only requirement on your host is the ability to make an HTTPS request, which every PHP host has. That is the specific gap Transformy's free tier (100 documents a month) lets you verify with your own templates.
The bottom line
Answer the server question and the list gets short. No install rights: stay pure-PHP with mpdf or TCPDF if your documents fit their ceiling, or step up to browser rendering with Transformy, where the free tier (100 documents a month, no credit card) is enough to run your real Blade templates through the migration table above. Your own servers: Browsershot brings Chrome into your PHP workflow, and Gotenberg gives it a service shape.
dompdf earned its place by making PDFs possible anywhere PHP runs. The alternatives above are for the day "possible" stops being the same thing as "good enough."