- A rendering step your PHP app shells out to or calls over HTTP — the
forme-htmlCLI on the same box, or a small Node service you own. - Moving PDF generation out of PHP entirely, if your stack is heading that way anyway.
composer require and in-process — DomPDF (or mPDF/TCPDF) remains your tool, and the rest of this page is not for you. Everyone else, read on: the template itself usually moves with few or no changes, because both tools speak HTML and CSS.
Why people leave DomPDF
The famous wall is no flexbox. DomPDF renders a useful HTML subset, but it predates modern layout: no flexbox, no grid, and partial support across much of CSS 2.1. Every DomPDF template is built from tables and floats because those are the tools that exist there. The secondary reasons are the ones you hit at 2am: UTF-8 and non-Latin scripts needing font gymnastics, PHP memory limits on long documents, and print-CSS features (@page margin boxes, page counters, break control) that are partially implemented or absent.
None of that is a criticism of a library that has carried PHP PDF generation for fifteen years. It is why the migrations happen.
What moves over unchanged
Your DomPDF template is HTML + CSS, and the dialect DomPDF taught you is inside Forme’s subset:- Tables, including
<thead>repeating on every page,colspan/rowspan, andborder-collapsewith Chrome-matched edge resolution. Cell overflow is preserved across page breaks. - Floats lay out as columns — the two-column address block, the
float: righttotals box, cleared sections. The one unsupported float case is text wrapping alongside a float (content renders below instead, with a warning naming it). - The cascade as written: type/class/id selectors, compounds, combinators, attribute selectors,
!important. - Print CSS, properly:
@pagesize and margins,:firstvariants, margin boxes withcounter(page)/counter(pages),break-*and the legacypage-break-*spellings,orphans/widows. - Text you don’t have to fight: OpenType shaping (ligatures, kerning), font fallback chains, automatic hyphenation, justified text with real inter-word distribution, BiDi for RTL scripts.
What doesn’t, up front
- No JavaScript execution (DomPDF doesn’t run it either, so nothing changes here).
- Nothing fetched over the network. Remote images and fonts are never downloaded. Inline images as data URIs or local paths; pass fonts explicitly with
--font Family=path.ttf— no font-directory installation dance, but also no implicit system fonts. - A documented subset, not all of CSS. Everything outside it — transforms, gradients, CSS variables — warns by name at render time instead of rendering differently in silence. The subset table is the reference, and the warnings list from one render of your own template is the ground truth.
Before and after
Before — DomPDF, in-process PHP:npx @formepdf/html or a global install):
Verifying the whole template set
The real fear is not “will one invoice render” — it is “will I silently break every invoice for one customer segment.” That is a structural question, and pdf-testkit answers it by diffing PDFs structurally, not by pixels:The measured number
Of 15 production templates collected from GitHub for our compat corpus — two of them stock Crater designs written specifically for DomPDF — 14 render correctly at 0.20.0, 1 degrades legibly with its cause named in warnings, 0 render broken (how it was measured). The two DomPDF-native templates are in the 14.Who should migrate, and who shouldn’t
Migrate if PDF generation is a service boundary you can draw — a CLI call, a container, a small endpoint — and your pain is layout (flexbox), text (UTF-8/RTL), or print CSS. The templates come with you. Don’t migrate if in-process PHP is a hard requirement. That constraint is legitimate and this library does not meet it. What to try first:npx @formepdf/html your-template.html -o out.pdf against your gnarliest real template, then read the warnings. One minute, and you will know which page of this guide matters to you. If something renders wrong without a warning naming it, file it — that is a bug on our side by contract.