moveek/excel-bundle
Moveek Excel Bundle simplifies Excel import and export in Laravel/PHP apps, offering a lightweight wrapper for reading spreadsheets and generating downloadable files. Configure sheets, mappings, and formatting, then integrate exports and imports into controllers or jobs with minimal code.
What it actually is. Strip the packaging and there is one fact a TPM needs: moveek/excel-bundle is a thin Symfony service-provider bundle around phpoffice/phpspreadsheet. The description calls it a "Laravel/PHP package" with "simple integration with Laravel applications"; the repository name, the bundle registration model, and the TPM assessment all say otherwise. That gap between marketing copy and code is itself the first finding — it means the README cannot be trusted as a source of truth about fit, and any adoption decision has to be based on reading composer.json and the bundle class, not the description.
Architecture fit. Poor against a Laravel target and marginal even against Symfony. The bundle's entire contribution is container wiring plus a config tree (temp directories, caching, reader/writer factories) — roughly the content of a 50-line service provider. There is no import/export domain model, no queue integration, no chunking, no streaming iterator, no response builder worth the name. PhpSpreadsheet is framework-agnostic; the wrapper adds a configuration surface and a dependency edge, nothing more.
Integration feasibility. Technically installable, practically not worth installing. Three options, in preference order:
phpoffice/phpspreadsheet directly, behind an internal SpreadsheetReader / SpreadsheetWriter interface we own.maatwebsite/excel if the team wants a Laravel-native wrapper — it already solves chunked reads, queued imports, and export responses, which are the actual hard parts.Option 3 is the sole scenario in which this repository matters, and it is contingent on an audit we have not done.
Technical risk. High, concentrated in supply chain rather than code quality (which is unassessed). Zero stars, zero dependents, a single maintainer, and no release history visible from here mean: no production users to find bugs, no security researcher watching, no community to absorb an upstream break, and no evidence the maintainer intends to keep pace with PhpSpreadsheet majors.
The transitive dependency is the sharp edge. PhpSpreadsheet parses untrusted uploaded files — XML, ZIP, shared strings — an area with a real CVE history. Placing an unaudited, unmaintained shim in front of it means our patch path runs through someone else's version constraint.
MIT licensing is the one clean signal: fork-and-own is legally unencumbered if we choose that route.
Key questions for the engineering owner.
composer.json declare, and does it install against current PhpSpreadsheet 2.x/3.x?Decision rule to put in front of the team: this is a no-go on adoption, regardless of the answers, because the best case is that it saves us a config file and the worst case is an emergency fork under incident pressure.
Stack fit. Reject. Symfony bundles and Laravel packages share Composer and PSR interfaces but not container semantics — no registerBundles(), no extension config tree, no tagged-service discovery. Forcing it in means either an uncommon Symfony-in-Laravel bridge (reject on complexity) or hand-instantiating services with the bundle's config layer bypassed (at which point the bundle contributes nothing we did not already have).
The leverage is as a pattern source, not a dependency. Frame the work this way to stakeholders: we are spending a day reading a small repository to confirm there is nothing in it we need, and we are buying a platform decision with that day. That is cheap diligence, not adoption.
Migration path.
config/excel.php. Bounded, well-understood work measured in hours.SpreadsheetReader / SpreadsheetWriter in the domain layer and bind PhpSpreadsheet to it. This is the load-bearing architectural decision — it makes the underlying library and any future wrapper choice swappable without touching call sites. Do this before any wrapper evaluation, or the wrapper decision will silently drive the architecture.Compatibility. Unverified and must be verified before any design commits to it: composer why-not phpoffice/phpspreadsheet against the version our security baseline requires, plus an install test on the target PHP runtime. A wrapper that constrains us out of upstream patches is a net negative independent of its features.
Sequencing for the roadmap. If three or more roadmap items need XLSX in or out — bulk customer/product import, admin export buttons, finance and reconciliation reports, scheduled report delivery, enterprise-onboarding migration tooling — that is the signal to invest in a shared spreadsheet layer once. The decision is about the layer, not this bundle. Build the layer on the upstream library, publish the interface, and let feature teams consume it.
Maintenance. The dominant cost, and it is asymmetric: adoption transfers a maintenance obligation to us without transferring any maintainer capacity. With zero dependents there is no community to absorb fixes, and the PhpSpreadsheet major-version treadmill becomes ours to manage through a shim we did not write. Be honest in the ADR — if we take this code, we own it. Name an internal owner or do not take it.
Support. No support channel, no issue history to mine for failure modes, no documented API contract. An on-call engineer debugging an export at 2 a.m. has an unfamiliar, undocumented codebase and no external reference. Contrast this with PhpSpreadsheet or Laravel Excel, where the failure mode is likely already answered in a public issue.
Scaling. Wrapper-independent, and therefore the real scaling risk: PhpSpreadsheet loads whole workbooks into memory by default. Large imports will exhaust PHP memory limits and blow request timeouts. The correct pattern is chunked reads on queue workers with explicit memory ceilings and bounded job timeouts. Temp files need a disk with a defined lifecycle and a sweeper — ephemeral container filesystems will silently accumulate or lose them, and concurrent exports against a shared temp path are a plausible collision hazard worth testing explicitly.
Failure modes, ranked by likelihood.
Ramp-up. Low for the code — a thin DI wrapper is a day's reading — but non-zero because there are no docs, no examples, and no prior team familiarity. The larger cost is organizational: getting reviewers to accept a zero-signal dependency in a production path. On reflection they should not, and that review conversation is itself the deliverable.
Recommendation and asks. No-go on adoption. Standardize spreadsheet work on PhpSpreadsheet directly (or Laravel Excel for queue-aware, model-bound flows), behind an internal interface.
Three decisions I want closed:
How can I help you explore Laravel packages today?