spatie/laravel-pdf
Create PDFs in Laravel apps from Blade views using Chromium (Browsershot, chrome-php), Gotenberg, Cloudflare Browser Run, WeasyPrint, or DOMPDF. Save to disk or return as a download, with full control over page format and modern CSS.
Architecture fit
spatie/laravel-pdf is a thin, opinionated facade over a pluggable rendering engine, not a PDF writer. That distinction matters architecturally: the package owns the Laravel-facing concerns (Blade view → HTML → PDF pipeline, storage/response handling, testing fakes, Blade directives) while delegating rasterization and pagination to a swappable driver. For a standard Laravel monolith or a modular monolith, it slots in with near-zero architectural friction: one composer dependency, one config file, one facade. No new datastore, no schema changes, no event bus.
The strategic value for a TPM is driver abstraction as a de-risking layer. Six drivers are supported with materially different operational profiles:
| Driver | Runtime dependency | CSS fidelity | Ops profile |
|---|---|---|---|
| Browsershot (Chromium) | Node + Puppeteer + Chromium co-located with PHP | Highest (grid, flex, web fonts) | Heavy images, memory spikes on PHP hosts |
| Gotenberg | Docker sidecar, HTTP API | Highest | Isolated, independently scalable — best for containers/K8s |
| Cloudflare Browser Run | Fully managed, no infra | Highest | Data egress to a third party; per-request cost |
| WeasyPrint | Python | Strong CSS Paged Media, weaker flex/grid | Lightweight, excellent page/header control |
| DOMPDF | Pure PHP | Limited (no grid/flex) | Zero system deps; ideal for dev/CI/fallback |
| chrome-php/chrome | Chromium via CDP | High | Similar to Browsershot, different client library |
Because application code (Pdf::view(...)->format('a4')->save(...)) is driver-agnostic, we can commit to the package while deferring — or later reversing — the runtime decision. That is the single largest technical risk reducer here.
Integration feasibility
Low. The public surface is small and conventional: Blade views plus a builder with format(), name(), save() (disk-aware), download/streamed responses, and per-page header/footer directives. The changelog shows steady, incremental hardening of exactly the integration points we care about — disk handling normalized in 1.5.3, name/download semantics corrected in 1.5.0/1.5.1, spatie/browsershot v5 support added in 1.5.3, Laravel 12 compatibility in 1.5.5. That is a package being polished rather than one still searching for its API.
A genuine differentiator is the testing story: Pdf::fake() with assertRespondedWithPdf() / assertDontSee() lets PDF generation participate in the normal feature-test suite, and pdftotext-based content assertions are supported. Most PDF tooling in the PHP ecosystem has no first-class test double; this one does. It ships a Laravel Boost skill as well, which measurably reduces AI-assisted codegen errors.
Technical risk
dependents: 0, a 39/100 composite, a future-dated last release of 2026-10-05) is internally inconsistent with a 1k-star, actively maintained Spatie package at 1.5.x. I would treat the score as unreliable and verify adoption against Packagist download stats and our own reference checks before weighting it.Key questions
Stack fit
Laravel 10–12 with PHP 8.x, Blade for templates, and existing filesystem disks for output. No new services required if DOMPDF is acceptable; one container if Gotenberg. The package reuses our existing view, storage, queue, and config conventions, so it does not introduce a parallel idiom that engineers must learn.
Migration path
Assume an existing barryvdh/laravel-dompdf, knp-snappy/wkhtmltopdf, or hand-rolled Browsershot implementation. Because the package renders Blade views, migration is mostly mechanical rather than a rewrite:
PDF::loadView(...)->setPaper(...)-style calls to Pdf::view(...)->format(...); keep views unchanged initially.DocumentRenderer interface so callers don't couple to the facade — this preserves the option to revert or dual-run.Compatibility
Existing disk abstraction and responses are respected; no conflict with queueing, Horizon, or Octane (though Octane plus co-located Puppeteer warrants a memory ceiling test). WeasyPrint and DOMPDF are additive, not exclusionary — we can ship DOMPDF in CI for speed and Gotenberg in production for fidelity, using driver configuration per environment. That environment-scoped driver strategy is worth adopting deliberately rather than discovering accidentally.
Sequencing
Maintenance
Package maintenance is light — Spatie ships regular point releases, mostly dependency bumps and small fixes, with clear changelogs. The real maintenance load is the render runtime: Chromium/Node or Gotenberg/Python image rebuilds, CVE patching, and font package updates. Budget for a recurring, if small, platform task, not a zero-cost dependency. Pin the composer constraint and review minor versions quarterly.
Support
Vendor risk is low: MIT license, well-known maintainer, documentation site, changelog discipline, active issue triage. No commercial SLA — support is community-based, so internal ownership must be explicit. Assign one engineer as the PDF domain owner; the knowledge is concentrated in CSS-for-print and container configuration, both of which are easy to lose.
Scaling
Rendering is CPU- and memory-bound and does not scale like typical PHP request handling. Two viable models:
Default to asynchronous: enqueue generation, store to a disk, and notify or serve a signed URL. This keeps user-facing p95 latency independent of document complexity and gives free retry semantics.
Failure modes
--no-sandbox, which weakens isolation. Gotenberg or a network-isolated sidecar mitigates this; document the decision.Ramp-up
Very low for application developers: the builder API is discoverable in under an hour and the docs are focused. Realistic estimate is 1–2 days for a mid-level Laravel engineer to ship a production-quality template, with the majority of that time spent on print CSS (page breaks, running headers, margins) rather than the package. Platform effort is higher and front-loaded — roughly 2–4 days to containerize and validate the render runtime, plus CI wiring for pdftotext/Puppeteer so the test fakes and content assertions run in the pipeline. The bundled Laravel Boost skill further lowers the cost of correct first-attempt code from AI tooling.
How can I help you explore Laravel packages today?