# Dompdf alternative for PHP
Dompdf alternative for PHP. Dompdf lacks flexbox and grid and slows on big tables. Compare mPDF and Browsershot, or render Chrome-quality PDFs.
Dompdf is the default answer for "HTML to PDF in PHP". It's pure PHP, installs with Composer and works well for simple documents. Teams often hit a wall when the HTML uses modern CSS or gets long.
This page covers the usual pain points, the main PHP alternatives, and how to call a Chrome-based API from PHP and Laravel.
**Quick answer.** Send your HTML to a hosted Chromium API and get the PDF back:
```bash
curl -X POST https://html-pdf.com/v1/pdf \
-H "Authorization: Bearer $HTML_PDF_KEY" \
-H "Content-Type: application/json" \
-d '{"html": "
Invoice #042
"}' \
-o invoice.pdf
```
## Common Dompdf problems
These are the issues that usually push teams away from Dompdf.
- **No flexbox or grid.** Dompdf implements its own layout engine, mostly CSS 2.1 with some CSS3. Layouts built with `display: flex` or `display: grid` collapse into stacked blocks.
- **Limited CSS3.** Many newer properties and selectors are partial or missing, so a template that looks right in Chrome looks different in the PDF.
- **Big tables are slow.** Long tables use a lot of memory and render time, and can hit PHP's `memory_limit` or `max_execution_time`.
- **Fonts take setup.** Custom fonts need to be registered or loaded with `@font-face` and a writable font cache. Missing glyphs show up as `?`.
- **No JavaScript.** Charts drawn with Chart.js or similar never render.
## PHP alternatives
Here are the three main options PHP developers move to.
**mPDF** is also pure PHP. It handles headers, footers, right-to-left and CJK text well. It also uses its own layout engine, so flexbox and grid have the same problem.
**Spatie Browsershot** drives real headless Chrome through Puppeteer, so CSS and JavaScript render like the browser. The cost is infrastructure. You need Node.js, Puppeteer, a Chrome binary and Chrome's system libraries on every server, which is awkward on shared hosting, slim Docker images and some serverless setups.
**A hosted Chrome API** gives Browsershot-style output with just an HTTP call from PHP.
## Comparison
This table compares the four options at a glance.
| | Dompdf | mPDF | Browsershot | html-pdf.com API |
|---|---|---|---|---|
| Engine | PHP layout engine | PHP layout engine | Headless Chrome | Headless Chromium (hosted) |
| Flexbox / grid | No | No | Yes | Yes |
| JavaScript | No | No | Yes | Yes |
| Server requirements | PHP extensions | PHP extensions | Node + Puppeteer + Chrome | None (HTTP) |
| Works offline | Yes | Yes | Yes | No |
| Cost | Free (LGPL) | Free (GPL) | Free (MIT) + servers | 1 credit per page |
## When Dompdf is the better choice
Dompdf is still the right tool in a few cases.
- Simple, table-based documents (basic invoices, letters) that you design for Dompdf from the start.
- Environments without outbound network access, or where HTML must never leave your server.
- Low volume, where adding a paid service isn't worth it.
If your templates already work in Dompdf and you're happy with them, there's no reason to switch.
## Calling a Chrome API from PHP
These examples show how to render a PDF from plain PHP and from Laravel.
### Plain PHP (cURL)
```php
Invoice #042
Total: $120.00
';
$ch = curl_init('https://html-pdf.com/v1/pdf');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 40,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('HTML_PDF_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'html' => $html,
'format' => 'A4',
'landscape' => true,
'margin' => '15mm',
]),
]);
$pdf = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status !== 200) {
throw new RuntimeException("PDF failed ($status): $pdf");
}
file_put_contents('invoice.pdf', $pdf);
```
### Laravel (Http client)
```php
use Illuminate\Support\Facades\Http;
Route::get('/invoices/{invoice}/pdf', function (App\Models\Invoice $invoice) {
$html = view('invoices.pdf', ['invoice' => $invoice])->render();
$response = Http::withToken(env('HTML_PDF_KEY'))
->timeout(40)
->post('https://html-pdf.com/v1/pdf', [
'html' => $html,
'format' => 'A4',
'margin' => '15mm',
'max_pages' => 20,
]);
abort_unless($response->successful(), 502, 'PDF generation failed');
return response($response->body(), 200, [
'Content-Type' => 'application/pdf',
'Content-Disposition' => "inline; filename=\"invoice-{$invoice->id}.pdf\"",
]);
});
```
In a real app, read the key through `config()` rather than `env()` so it still works after `php artisan config:cache`. Your Blade views can keep using Tailwind, flexbox or grid.
Images and fonts must use absolute `https://` URLs or data URIs, because the renderer can't reach `localhost`.
## Mapping Dompdf calls
This table shows the html-pdf.com option for each common Dompdf call.
| Dompdf | html-pdf.com |
|---|---|
| `$dompdf->setPaper('A4', 'landscape')` | `'format' => 'A4', 'landscape' => true` |
| `setPaper('letter', 'portrait')` | `'format' => 'Letter'` |
| `setPaper([0, 0, 612, 1008])` (points) | `'width' => '8.5in', 'height' => '14in'` |
| `isRemoteEnabled` | Not needed; public `https://` assets load |
| `$dompdf->stream('file.pdf')` | `'filename' => 'file.pdf'` and return the body |
| `$canvas->page_text(...)` page numbers | `footer_html` with `pageNumber` / `totalPages` |
| `@page { margin: ... }` | Keep it with `prefer_css_page_size`, or use `margin` |
For page numbers, add a footer and leave room for it with a bottom margin.
```php
'margin' => ['top' => '15mm', 'right' => '12mm', 'bottom' => '20mm', 'left' => '12mm'],
'footer_html' => 'Page of
',
```
## Or skip the server
html-pdf.com lets you get Chrome-quality PDFs without installing Node, Puppeteer or Chrome on your PHP servers. It's a hosted HTML and URL to PDF API on headless Chromium.
Send `POST https://html-pdf.com/v1/pdf` with a Bearer key and `{"html": "..."}` or `{"url": "https://..."}`. You get back a PDF with selectable text, as binary, base64 or a 24-hour link.
1 credit = 1 PDF page. You get 100 free credits once, then packs run from $10 for 1,000 pages to $250 for 50,000 ($0.01 to $0.005 per page), and purchased credits never expire. A [remote MCP server](https://html-pdf.com/pdf-mcp-server) is also available for AI assistants.
## FAQ
### What is the best Dompdf alternative for flexbox and grid?
A Chrome-based renderer. Browsershot runs headless Chrome on your own server, and html-pdf.com runs Chromium as a hosted API, so flexbox, grid and JavaScript render like the browser. mPDF has the same layout limits as Dompdf.
### How do I add page numbers when moving off Dompdf?
Replace `$canvas->page_text(...)` with a `footer_html` that contains `` and ``. Leave a bottom margin so the footer has room.
### Is there a free Dompdf alternative?
mPDF and Browsershot are free open-source libraries, though Browsershot needs Chrome on your servers. html-pdf.com gives you 100 free credits once with no card, and 1 credit is 1 PDF page.
### Can I use html-pdf.com from Laravel?
Yes. Render your Blade view to HTML and post it to `https://html-pdf.com/v1/pdf` with `Http::withToken(...)`, as in the example above.
[Get a free API key](https://html-pdf.com/login) · [API docs](https://html-pdf.com/docs) · [HTML to PDF in PHP](https://html-pdf.com/html-to-pdf-php) · [HTML to PDF in Laravel](https://html-pdf.com/html-to-pdf-laravel) · [Page breaks](https://html-pdf.com/html-to-pdf-page-breaks)