sylius/pdf-generation-bundle
Sylius PDF Generation Bundle adds PDF document creation to Sylius stores, enabling configurable invoices, order confirmations, and other printable documents through flexible templates and service-based integration.
Architecture fit. The first and most important finding for a TPM: this is a Symfony bundle, not a Laravel package. It is written against Symfony's DI container, service tags, compiler passes, ServiceLocator, and PHP attributes consumed by Symfony's autoconfiguration. It has no service provider, no facade, no Laravel-native config publishing. If the target application is Laravel, the bundle cannot be dropped in as-is; the value you get is the interfaces and reference implementations, not the wiring. Treat it as a well-organized reference architecture rather than an install-and-go dependency. Its conceptual design (context → adapter → generator provider → options processor → storage) is portable, but the plumbing is Symfony-specific.
Integration feasibility. For a Symfony/Sylius shop the fit is strong and idiomatic: YAML config cascades from default into named contexts, built-in adapters (knp_snappy, dompdf, gotenberg) are auto-detected, custom adapters are deferred to a compiler pass, and storage is swappable per context (Flysystem, Symfony Filesystem, Gaufrette). For Laravel, integration requires either (a) manually instantiating the interfaces in a bespoke service provider and hand-wiring generators/processors, or (b) running a second Symfony kernel — neither is attractive. The realistic Laravel path is to reuse the domain contracts (PdfGenerationAdapterInterface, OptionsProcessorInterface, PdfStorageInterface) and back them with Laravel-native equivalents (barryvdh/laravel-dompdf, spatie/laravel-pdf / Browsershot / Gotenberg client, Storage facade).
Technical risk. High, for a handful of reasons:
Key questions to raise before adoption:
sylius/sylius internals? If it's a mirror of upstream Sylius code, the maintenance trajectory follows Sylius; if it's an independent effort at 3 stars, it may be abandoned.Stack fit. Strongly positive on Symfony/Sylius; negative on Laravel. If the product is Sylius-based, plan to adopt it directly. If the product is Laravel, do not attempt to load the bundle; instead pull the interfaces as a design template.
Migration path.
composer require sylius/pdf-generation-bundle, add sylius_pdf_generation config with a default context, install one adapter package (knplabs/knp-snappy-bundle, dompdf/dompdf, or gotenberg/gotenberg-php), choose one storage backend, and define named contexts (invoice, receipt, coupon). This is a low-friction first integration — days, not weeks.PdfGenerationAdapterInterface and OptionsProcessorInterface, implement a DompdfAdapter and a GotenbergAdapter, and bind a ContextAdapterRegistry in a service provider keyed by context name. This reproduces ~80% of the bundle's value in ~1–2 weeks without dragging in Symfony's container semantics.Compatibility. Confirm PHP version, Symfony minor version, and the exact adapter package versions against your project matrix. The bundle's LogicException on missing adapter classes is a helpful fail-fast, but it means you must install the adapter's Composer package even if a given context is configured but unused at runtime. Verify Flysystem major version — the ecosystem has moved from v1/v2 to v3 and storage adapter classes change accordingly.
Sequencing. Recommended order for either stack:
local_cache_directory for remote backends so resolveLocalPath() works (this is the sharpest operational edge: remote storage implementations lazily materialize a local copy).invoice, credit_note, coupon) not after templates.Maintenance. This is the dominant operational concern. At 3 stars and 0 dependents, you are effectively on the hook to fork or vendor the package if it stops updating. MIT licensing makes that legally trivial, but it converts the bundle from "dependency" to "internal component with an upstream mirror." Budget for a quarterly review of upstream commits and a fallback plan: keep the adapter interfaces thin enough that swapping to a maintained alternative (e.g., direct Gotenberg client, or Laravel-side spatie/laravel-pdf) is a sprint, not a quarter.
Support. No vendor SLA, no commercial backing visible. Support model is community/Sylius channels plus reading the source. The in-repo AGENTS.md is unusually good documentation and materially lowers ramp-up, but it is the team's own words, not external validation.
Scaling.
local_cache_directory is on fast local disk and has a bounded TTL/eviction policy, because lazy materialization in resolveLocalPath() can silently fill disks.Failure modes to instrument from day one.
RegisterKnpSnappyPrototypePass exists precisely to avoid this, but custom adapters can reintroduce it.resolveLocalPath() for remote backends → cache directory unreadable/unwritable; alert on disk utilization.Ramp-up. For a Symfony team, one engineer can go from reading AGENTS.md to a working invoice context in 1–2 days. For a Laravel team, expect 1–2 weeks to re-implement the pattern and to unlearn Symfony's container idioms; the bundle's concepts (context routing, swappable adapters, option-processing chain) transfer cleanly, but none of the DI wiring does. Across the organization, the main skill investment is ops for whichever adapter you pick — running Chromium/Gotenberg in containers is the real learning curve, not the PHP.
TPM recommendation. Do not adopt as a direct dependency for a Laravel application — architecturally incompatible at the framework layer. For a Symfony/Sylius application, it is a clean, well-factored option provided you (a) verify the release-date anomaly on Packagist, (b) commit to Gotenberg or Dompdf rather than wkhtmltopdf, and (c) accept custodial risk given the 3-star/0-dependent footprint with a documented exit path. In either case, the highest-value artifact to borrow is the interface design and context-routing model, which is sound and portable.
How can I help you explore Laravel packages today?