1tomany/pdf-pack-bundle
Symfony bundle wrapping the 1tomany/pdf-pack library for PDF extraction. Autowires read and convert actions to fetch metadata, rasterize pages to PNG, and extract text, with configurable Poppler binaries.
Architecture fit — the bundle is a poor fit; the underlying library is a reasonable one.
This package is a Symfony bundle, not a Laravel package. Everything it actually adds over 1tomany/pdf-pack is Symfony-specific plumbing: a YAML configuration tree, a DI extension, and a tagged-service mechanism (onetomany.pdfpack.client with a key) resolved through a compiler pass. None of that machinery executes in Laravel. The value proposition for a Laravel team therefore collapses to zero — there is no Symfony kernel to consume the config, no autoconfigure pass to alias ExtractActionInterface to a concrete client, and no when@test block semantics.
What is genuinely portable is the wrapped library. 1tomany/pdf-pack is plain PHP with clean, framework-agnostic seams: ExtractActionInterface / ReadActionInterface for consumers, ClientInterface for implementers, immutable request DTOs (ReadRequest, ExtractRequest) with a fluent builder (fromPage(), toPage(), asPngOutput(), atResolution()), and typed responses. That is a natural fit for Laravel's container and DTO-friendly job classes. The MockClient is a legitimate asset for CI.
Integration feasibility — feasible, but you are re-implementing the bundle's only contribution.
Wiring the library into Laravel is roughly 20–40 lines in a service provider: singleton-bind the two action interfaces to the concrete client, and move the YAML keys into config/pdfpack.php backed by env(). The friction is that the README never names the concrete client classes or their constructor signatures — the Symfony bundle resolves them opaquely. Your first engineering task is reading upstream source to learn how to construct PopplerClient (or whatever the class is named) manually. On an archived repository, that source read is also the only documentation you will ever get.
Technical risk — high, and dominated by one non-technical fact.
| Risk | Severity | Notes |
|---|---|---|
| Repository is archived | Critical | No fixes, no security patches, no answers to the constructor-signature question above. Anything you adopt, you own forever. |
| Single-vendor, single-maintainer | High | One author (1:N Labs). 1 star, 0 dependents — essentially no third party has validated this in production. No blast radius means no battle-testing. |
| Dependency churn already happened | High | Release history shows renames mid-flight: pdf-to-image → pdf-ai → pdf-pack. APIs you learn today were already renamed twice and will not be renamed again — because nobody is maintaining them. |
| External OS-level dependency | High | Requires Poppler binaries (pdfinfo, pdftoppm, pdftotext) in every environment. Note the README's pdftoppm_binary: "pdftppm" typo — a direct example of the misconfiguration class you will hit. |
| Symfony 8 requirement (v0.5.3) | Medium | Pulls modern PHP constraints into your root composer.json; may collide with a Laravel app on an older PHP minor. |
| Untrusted input → subprocess | Medium | Poppler has a CVE history with malicious PDFs. Sandboxing and resource caps are your responsibility. |
| Test coverage unknown | Medium | Maturity is "readme, releases" — no evidence of a suite. Assume none. |
Key questions to resolve before committing engineering time
1tomany/pdf-pack library also archived, or is only the Symfony wrapper? If the library is alive, adopt the library directly and ignore this package entirely.smalot/pdfparser is pure PHP with no OS dependency — a far cheaper operational bet.TPM recommendation: Conditional Go, scoped narrowly. Do not adopt the bundle. Evaluate 1tomany/pdf-pack directly against spatie/pdf-to-image (Ghostscript/Imagick, actively maintained) and smalot/pdfparser (pure PHP). Only proceed with the 1tomany library if a Poppler-backed rasterization workload is confirmed and you are willing to fork.
Stack fit. Target Laravel 10+ on PHP 8.2+. Do not attempt to install the Symfony bundle into a Laravel app — Composer will resolve it, but nothing will wire up, and the Symfony DI/config components become dead weight in your dependency graph. The integration surface is the library plus a hand-written PdfPackServiceProvider.
Two viable paths.
Path A — library-direct with a Laravel provider (recommended). Bind the action interfaces as singletons, publish a config/pdfpack.php translating the YAML keys 1:1, and swap to MockClient under $this->app->environment('testing'). This mirrors what the bundle does, in ~30 lines, with no Symfony coupling and full visibility into construction.
Path B — fork-and-flatten (only if you need the config ergonomics). Fork the repo, strip the Symfony extension, keep the client wiring. Higher carrying cost; only justified if multiple teams consume the package and you want a shared internal abstraction.
Compatibility translations to plan for explicitly.
| Bundle mechanism | Laravel equivalent |
|---|---|
config/packages/onetomany_pdfpack.yaml |
config/pdfpack.php + .env |
Autowire ExtractActionInterface |
$this->app->singleton(...) in register() |
when@test: config block |
$this->app->environment('testing') conditional binding |
Tagged service + key resolution |
Explicit match() on the config client value, or a small factory |
| No HTTP layer | Controller or queued job injects the interface directly |
Sequencing — five steps, each gated.
smalot/pdfparser and spatie/pdf-to-image. Gate: is Poppler's quality delta worth the OS dependency and the archived-maintainer risk?poppler-utils pinned, Composer version lock, MockClient in the test suite.Migration path out. The surface is small and MIT-licensed: two interfaces, two request DTOs, two response types. Wrap the library behind your own narrow port (PdfExtractor) so a future swap to Ghostscript, a SaaS API, or a microservice is a single adapter change rather than a sweep through business logic. This adapter is the single highest-leverage architectural decision in the whole engagement.
Maintenance — you inherit the full burden. Archived means no CVE response, no PHP 9 readiness, no Symfony/Poppler compatibility patches. Budget a named internal owner and, realistically, 2–5 days per year of fork upkeep. The offsetting factor is small surface area: the library is a thin shell over CLI binaries, so the actual code you must understand is minimal. Treat the fork as a vendored internal package, not a dependency.
Support. No upstream channel. Internal Slack channel plus a documented runbook is your entire support model. This must be agreed before go-live — an unowned archived dependency discovered during an incident is a bad incident.
Scaling. Extraction is CPU- and memory-bound subprocess work; it is not a request-path operation at any meaningful volume. Design:
pdf queue and its own worker pool. Never inside a web request.pdftoppm call can consume hundreds of MB at 150+ DPI on a large document. Cap --max-time and worker count so one 400-page PDF cannot starve the pool.poppler-utils, distinct from web containers. Keeps the OS dependency off your front-end tier.Failure modes to instrument from day one.
pdftoppm/pdftppm typo is the canonical example. Fail loudly at boot (a health check that shells pdfinfo -v), not on first customer PDF.extract() yields page-by-page, so a failure on page 40 delivers 39 pages then dies. Consumers must treat output as all-or-nothing; buffer to storage and only promote on clean completion. Also, an early break out of the generator may orphan the subprocess — always drain.Ramp-up. Low-to-moderate for a mid-level Laravel engineer: the API is small and the fluent request builder is pleasant, but they must learn Poppler's flags, Laravel service-provider wiring, and queue/worker separation. The MockClient meaningfully shortens CI onboarding — make it the default in phpunit.xml and never let the test suite touch the filesystem or a subprocess. Estimate: one engineer productive in 2–3 days, production-confident in 2 weeks.
Decision framing for stakeholders. Adopt only if (a) Poppler-grade extraction is a confirmed requirement that alternatives do not meet, (b) volume is bounded and queueable, and (c) you accept fork ownership. Otherwise, standardise on an actively maintained alternative — the 1-star, zero-dependent, archived profile is precisely the risk profile a TPM exists to avoid.
How can I help you explore Laravel packages today?