Dompdf alternative for PHP

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:

curl -X POST https://html-pdf.com/v1/pdf \
  -H "Authorization: Bearer $HTML_PDF_KEY" \
  -H "Content-Type: application/json" \
  -d '{"html": "<div style=\"display:flex\"><h1>Invoice #042</h1></div>"}' \
  -o invoice.pdf

Common Dompdf problems

These are the issues that usually push teams away from Dompdf.

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.

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
$html = '<div style="display:flex;justify-content:space-between"><h1>Invoice #042</h1><p>Total: $120.00</p></div>';

$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)

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.

'margin' => ['top' => '15mm', 'right' => '12mm', 'bottom' => '20mm', 'left' => '12mm'],
'footer_html' => '<div style="font-size:9px;width:100%;text-align:center">Page <span class="pageNumber"></span> of <span class="totalPages"></span></div>',

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 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 <span class="pageNumber"></span> and <span class="totalPages"></span>. 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 · API docs · HTML to PDF in PHP · HTML to PDF in Laravel · Page breaks

This page as markdown · text