Product Decisions This Supports
- Build vs. buy for document generation. This package is the "buy" half of a hybrid decision: you don't write PDF plumbing, but you do own the HTML/CSS templates that encode branding, legal copy, and layout. The real product investment shifts from rendering code to template and design-system ownership — which is where differentiation actually lives (invoice clarity, statement readability, branded collateral).
- Replacing a deprecated rendering stack. The README explicitly positions it as a drop-in replacement for KnpLabs/snappy (same
GeneratorInterface method contract). That makes "migrate off wkhtmltopdf/Snappy" a concrete, low-drama roadmap item rather than a rewrite, and it's a decision worth making deliberately given upstream wkhtmltopdf stagnation.
- Compliance and archival requirements. First-class support for PDF/A variants, PDF versions, XMP metadata, attachments, and PDF/UA-style tagging (
--pdf-tags) turns "can we produce archivally valid invoices/contracts/records?" from a custom engineering project into a configuration flag. This directly unblocks regulated document types (finance, healthcare, public sector, legal).
- Accessibility as a shippable feature. Tagged PDF output means accessibility can appear on the roadmap as a deliverable rather than an open-ended risk item — relevant for public-sector procurement and WCAG-adjacent commitments.
- Data-residency and vendor-surface decisions. Generating documents in-house vs. posting customer PII to a third-party PDF SaaS is a real product/compliance tradeoff. This package keeps document data inside your infrastructure, which is often the deciding factor for finance and HR documents.
- Cost model decisions. No per-document metering, MIT license. The cost shifts from variable per-render fees to fixed infrastructure (a Python runtime in your image, fonts, native libraries). At low-to-moderate volume this is cheap; it also makes cost forecasting deterministic for finance.
- Print-fidelity use cases. Invoices, statements, payslips, certificates, tickets, shipping labels, report exports, and "download as PDF" from an HTML view — all cases where the source of truth is already HTML/CSS and you want one rendering path, not two.
- Roadmap sequencing on infrastructure. Because WeasyPrint requires a Python runtime plus native libraries, adopting this forces an early decision about container images and deployment targets — a decision that shapes several other roadmap items and is better made once, explicitly, than discovered mid-sprint.
When to Consider This Package
Adopt when:
- The team is on PHP 8.3–8.5 and can ship a container image with Python and WeasyPrint's native dependencies (Pango/HarfBuzz and friends). If the deploy target already builds custom images, this is nearly free; if it's shared hosting or a locked-down serverless runtime, it is not.
- Documents are best expressed as HTML/CSS with print semantics —
@page rules, running headers and footers, page counters, footnotes, widows and orphans. This is exactly where WeasyPrint is strongest and where wkhtmltopdf-class tools fall down.
- You need genuine PDF standards output (PDF/A, tagged PDF, attachments, XMP metadata) rather than "a PDF that opens."
- You're already on Snappy/wkhtmltopdf and want a maintained, strictly-typed, security-hardened replacement without rewriting template code.
- Generation happens in background jobs, not in a user-facing request cycle. The default 10-second process timeout (and the explicit guidance to disable it inside queue workers) signals the intended deployment shape.
- You want a small, auditable dependency surface: one thin adapter over a CLI, MIT-licensed, with a documented list of what it does and does not do.
Look elsewhere when:
- You need JavaScript executed before rendering (chart libraries, client-side layout). Headless Chrome tooling is the right answer; WeasyPrint does not run JS. Decide this early — it's the single most common reason a PDF project gets rebuilt.
- You need image or screenshot generation. The image generator is deprecated and removed; for WeasyPrint 53+ this package is PDF-only. Use a browser-based snapshot tool.
- You need to merge multiple HTML sources into one PDF. Explicitly unsupported — one input source per output. Multi-source documents require a separate merge step.
- Hosting cannot run CLI binaries. Pure-PHP renderers (Dompdf, mPDF) or a SaaS PDF API fit better, at the cost of CSS fidelity and/or data egress.
- You expect Laravel-native ergonomics out of the box. This is a framework-agnostic Composer library — no service provider, facade, config file, or queue integration ships with it. You will write that binding yourself; budget a small internal adapter as part of the adoption cost, not as an afterthought.
- You require vendor SLAs, enterprise support, or a large integration ecosystem. With roughly 80 stars, zero dependents, and a single originating team, this is a credible but small project. Treat it as "small dependency with a real but unstaffed-by-you maintenance tail," not as a platform.
- You need sub-second synchronous rendering at high concurrency. Process-per-document is the model; a managed API or a pre-warmed worker pool is the alternative.
- Accessibility output must pass formal third-party audit. Tagging support exists and is a strong signal, but validate actual PDF/UA conformance in a pilot before committing to a compliance claim.
How to Pitch It (Stakeholders)
To executives: This is a small, MIT-licensed, low-lock-in library that lets us generate PDFs from HTML we already own, without per-document fees and without sending customer data to a third party. It unlocks document types we currently can't produce cleanly — archival-grade PDF/A invoices, accessible tagged documents, branded statements — through configuration rather than custom builds. The main cost is operational: our deploy images need a Python runtime alongside PHP. The main risk is vendor depth: the project is small, actively released, but not backed by a large ecosystem. Because the library is thin and MIT-licensed, our exit cost is low — we can swap the rendering engine behind our own interface without touching templates. Recommendation: approve a bounded pilot on one document type, with the integration hidden behind an internal service so the decision stays reversible.
To engineering: It's a typed, string-only adapter over the WeasyPrint CLI, deliberately mirroring Snappy's GeneratorInterface so migration is mostly namespace changes. It's stricter than Snappy in the ways that matter: PHP 8.3+, declared return types, backed enums for constrained options, and — most importantly — the process is executed from an argument array and never through a shell, so command injection through filenames, options, or the binary path is structurally impossible rather than merely escaped. The security history is a genuine positive signal: shell-injection, SSRF, temp-file deletion, and PHAR-deserialization issues have all been closed in the 2.5.x–2.6.x line, and upstream WeasyPrint option support tracks releases closely. Two constraints to design around: the package version is coupled to the WeasyPrint CLI version (pin both together), and there is no multi-source merge or image generation. Set the timeout deliberately — disable the internal one inside queue workers and let the worker manage it, and pin the WeasyPrint binary in the image so a base-image update doesn't silently change rendering. Given zero dependent projects in the wild, wrap it behind our own interface and add an integration test that renders a representative document on every deploy.