viest/xlswriter
High-performance PHP extension for reading and writing Excel XLSX files with low memory usage. Built in C on libxlsxwriter, it supports formulas, charts, images, formatting, conditional formatting and data validation—fast, reliable and ideal for large exports.
Architecture fit. viest/xlswriter is a PHP C extension wrapping libxlsxwriter, not a Composer library. That single fact dominates the architectural decision: it is a host capability, like pdo_mysql or gd, rather than a dependency you declare in composer.json. It fits well where the product needs a high-volume, write-only XLSX export path — nightly reports, statement generation, bulk data extracts — because it writes to disk via C with an order-of-magnitude lower memory and CPU profile than PhpSpreadsheet. It does not fit where the product needs to read, modify, or round-trip workbooks; the library is write-only by design, and there is no reader to fall back on. It also does not fit serverless-first or shared-hosting deployment targets, where you cannot install a PECL extension at all.
Integration feasibility. Technically straightforward for a team already shipping custom Docker images: install libxlsxwriter plus the extension in a build stage, pin the version, and the procedural API ($excel = new \Vtiful\Kernel\Excel($config)) is a few dozen lines to produce a formatted multi-sheet workbook. The use_disk_cache/memory-mode option means arbitrarily large exports are bounded by temp disk rather than RAM, which is the main reason to prefer it over pure-PHP writers. The friction is entirely environmental: per-PHP-minor rebuilds, musl/Alpine edge cases, Windows only via prebuilt DLLs, and no autoload fallback if the extension is absent — a missing extension is a fatal class-not-found, not a graceful degradation.
Technical risk. The top risk is availability drift: the extension must be recompiled for every PHP minor upgrade, and a base-image bump that silently drops it will take out exports at runtime rather than at build time unless you assert extension presence in CI. The second is blast radius: a segfault in a C extension kills the whole PHP-FPM worker, not just the request, so a malformed input can surface as intermittent 502s under load rather than a clean exception. Third is bus factor and documentation: a small maintainer group, historically documentation skewed toward Chinese-language sources, and no meaningful packaging ecosystem around it. Note the dependents: 0 figure is a measurement artifact — because it installs via PECL rather than Composer, standard SCA/SBOM tooling will not see it at all, which is a governance gap you should close manually rather than read as "nobody uses this." License (BSD-2-Clause) is permissive and unproblematic.
Key questions.
Stack fit. Best fit is a Laravel app on containerised infrastructure with a queue worker tier, exporting to local scratch disk then streaming to S3. Poor fit for Vapor/Lambda or any environment where you don't control the PHP build. Because the extension is invisible to Composer, it should be tracked explicitly in the platform's base-image Dockerfile and in an infrastructure dependency register, not in composer.json.
Migration path. Do not replace PhpSpreadsheet wholesale on day one. Introduce a narrow seam first: an WorkbookExporter interface (or Laravel contract) with export(ReportDefinition $def): string returning a temp path, plus two implementations — the existing pure-PHP one and a new XlswriterExporter. Route through a config flag per export type. This gives you a working fallback on developer machines and CI runners that lack the extension, keeps the diff small, and makes the performance comparison empirical rather than asserted. Retire the pure-PHP path only for exports that have been benchmarked and proven stable on the new adapter; keep the fallback permanently for portability rather than as dead code.
Compatibility. Target one PHP minor line and one extension version, pinned by exact version in the image build, with an explicit php -m | grep xlswriter assertion in the Dockerfile and a smoke test in CI that generates a file and validates it opens. Validate that the extension's supported styling surface covers what the product actually needs — number formats, merged cells, column widths, hyperlinks, freeze panes are solid; conditional formatting, charts, and pivot-adjacent features should be verified against the exact binding version rather than assumed from libxlsxwriter's C feature list.
Sequencing.
Maintenance. Ongoing cost is concentrated in the platform layer, not the application: each PHP upgrade is a rebuild-and-verify task, and each base-image change is a chance to lose the extension silently. Application-side maintenance is low — the API is stable and procedural. The real maintenance burden is ownership: with no Composer dependents, no vendor security feed will alert you to issues, so someone must actively watch the upstream repo and the underlying libxlsxwriter for CVEs and breaking changes. Budget a recurring half-day per quarter plus the PHP-upgrade ticket.
Support. Expect a thinner answer base than PhpSpreadsheet when something goes wrong; internal documentation of the adapter and its quirks (date handling, formula strings, locale-dependent number formats) is worth writing once rather than rediscovering. Debugging a crash means reading C-level failures, which most PHP teams cannot do in-house — the practical mitigation is input validation and isolation, not debugging.
Scaling. This is the strongest argument for the package. Constant-memory disk-backed writes let a single worker produce files that would OOM a pure-PHP writer, so throughput scales by adding queue workers rather than by enlarging containers. Two dimensions need capacity planning: ephemeral disk on the worker fleet (concurrent large exports multiply temp usage — set a concurrency cap per node) and the fact that the work is CPU-bound in the PHP process, so workers doing exports will not simultaneously serve other jobs well. For very large exports, prefer queue-and-notify over synchronous download so the request path never holds an open connection for minutes.
Failure modes.
pm.max_requests), and canary traffic on new inputs.finally, and alert on disk headroom.=, +, -, @ written into cells become live formulas when opened in Excel; this is a security issue a TPM should explicitly require the team to address, independent of the writer chosen.Ramp-up. Low for application developers — a mid-level PHP engineer can produce a correct formatted multi-sheet export in a day or two, and the mental model is familiar from any spreadsheet writer. Ramp-up risk sits with the platform team (image builds, extension verification) and with whoever owns the PHP-upgrade runbook. Realistically: one engineer-day to integrate the first export, one to two days to build the adapter abstraction and CI smoke test, and a standing platform commitment thereafter. The decision is worth it if write-only, high-volume exports are core; it is not worth it for a handful of small reports where PhpSpreadsheet's portability is the better trade.
How can I help you explore Laravel packages today?