littlerocket/pdf-bundle
littlerocket/pdf-bundle adds PDF generation to PHP applications, wrapping a PDF engine in a simple, configurable service for rendering HTML to PDF and streaming or saving documents. Lightweight setup and sensible defaults for common PDF workflows.
Architecture fit — framework mismatch is the headline. Despite being presented as a "Laravel/PHP package," this is a Symfony bundle: it ships a Bundle subclass, a DI Extension, and a config tree, all of which exist to wire PHPPdf into Symfony's container. Laravel does not register Symfony bundles. In a Laravel application, roughly all of the package's value (autoconfiguration, service wiring, config schema) is dead weight; only the underlying psliwa/php-pdf-derived rendering library is reusable, and even that would be consumed directly rather than through this bundle. Treat this as "a library we might vendor," not "a package we install."
Integration feasibility — likely blocked at the composer level. The description ("Fixed for PHP7") plus the 2023 release date implies a PHP 7.x floor and probable symfony/* version pins that conflict with Laravel 10/11 (PHP 8.1+/8.2+). Expect composer require to fail on platform or conflict constraints, with --ignore-platform-reqs as the only workaround — which is not an acceptable production posture. The real integration cost is not installation; it is either (a) adopting a fork we control and backporting PHP 8 support, or (b) extracting the rendering engine and wrapping it ourselves.
Technical risk — high and concentrated in upstream abandonment. PHPPdf is an effectively abandoned predecessor-generation renderer: an XML-markup DSL (stylesheets + node templates) compiled to PDF, historically leaning on Zend-era components. The fork has 0 stars, 0 dependents, and a composite score of 0.06 — there is no community, no CVE triage, no downstream signal that anyone is exercising this code in production. Additional risks:
Key questions to resolve before any code is written:
Verdict: do not adopt as a dependency. Use only as a migration source if legacy templates exist, and even then, vendored under our own namespace.
Stack fit. Assume Laravel. Do not install the bundle. Instead, create a first-party adapter package that depends on a fork we own, and bind it behind a narrow PdfRenderer interface (render(TemplateRef, Data): PdfDocument). This is the single highest-leverage decision: it makes the renderer swappable, which converts an abandonment risk into a routine refactor.
Migration path.
Compatibility. If a fork is unavoidable: host it in a private VCS repo we control (repositories entry in composer.json), pin an exact commit, and use cweagans/composer-patches only for small, documented fixups. Never depend on the public repository by branch name. Explicitly verify the PHP version matrix and the transitive PDF-writer dependency; run composer why-not php 8.2 early.
Sequencing. Abstraction and golden files come before the renderer decision, because they are useful regardless of which renderer wins. This de-risks the schedule: if the replacement evaluation stalls, we still have a safer legacy integration than the status quo.
Maintenance — we become the maintainer. There is no upstream to lean on. Budget recurring engineering time for dependency drift, PHP minor-version bumps, and font/asset path issues — realistically 1–3 days per quarter for a small document set, more if the template corpus is large. Add the fork to our internal dependency register and our vulnerability-scanning allowlist so it does not silently rot.
Support. No vendor, no SLA, no meaningful issue tracker activity, no Stack Overflow corpus. Every defect is debugged from source. This is acceptable for a bounded, non-customer-facing batch job; it is not acceptable for anything on a revenue-critical path.
Scaling. PHPPdf renders in-process and builds the document in memory. Consequences:
memory_limit becomes a functional limit, not a safety net — large tables and high page counts are the classic failure. Instrument peak memory per document type and set a per-job ceiling.Failure modes to instrument for:
| Failure | Symptom | Mitigation |
|---|---|---|
| Memory exhaustion | worker killed, job retried forever | per-job limit, dead-letter queue, page-count guard |
| Malformed/unsafe XML | parse exception or entity expansion | disable external entities, validate against a schema, never accept user-supplied markup |
| Silent layout drift | "valid" PDF, wrong output | golden-file diff in CI |
| Missing fonts/assets | fallback glyphs, wrong metrics | bake assets into the image, not the filesystem |
| PHP upgrade breakage | fatal on language semantics | pin runtime, test on the fork before any framework upgrade |
Ramp-up. The XML stylesheet DSL is idiosyncratic and effectively undocumented at this point; expect 1–2 weeks before a developer is productive and considerably longer before they can debug layout edge cases confidently. Onboarding risk is high precisely because there is no community to ask. Mitigate by ensuring at least two engineers touch the adapter and by writing the internal "how our PDFs work" doc that does not exist upstream — that doc is the real deliverable here.
Bottom line for planning: treat this as technical debt inherited, not a capability acquired. Fund the interface abstraction and golden-file harness as the primary workstream, and the renderer replacement as the follow-on; the package itself should never appear on a roadmap as a solution.
How can I help you explore Laravel packages today?