netipar/laravel-chunky
Resumable, chunk-based file uploads for Laravel. Send large files reliably over flaky connections with server-side chunk tracking and fingerprint-based resume. Typed backend plus Vue, React, Alpine and Livewire frontends. No queue worker or broadcasting required by default.
composer require + npm install. That is a roadmap-capacity decision: it buys back engineering weeks for the features that actually differentiate the product.auto mode means files under 256 MB assemble in-request with no queue worker and no broadcasting. This supports launching the feature without touching ops: no new worker, no Reverb/Echo, no capacity review. Queue and direct-to-S3 are config-level escalations later — the client API (upload/pause/resume/cancel/subscribe) does not change, so the scale decision is deferred without accruing rework debt.transport() => 'direct_s3' moves bytes out of Laravel entirely (assembly is CompleteMultipartUpload). Useful for deciding when to invest in S3 multipart plumbing — the answer can be "not now, and not by rebuilding the client."Consider it when:
auto mode plus chunky:doctor (which exits non-zero on failures, usable as a CI/deploy gate) fits a small team with limited ops capacity.docs/en/protocol.md), OpenAPI spec, and make:chunky-profile scaffolding make an internal fork realistically maintainable.Look elsewhere when:
direct_s3 path covers S3, MinIO, and R2 best-effort; GCS/Azure would be custom work.Adoption gate (do before committing): run chunky:doctor in staging, integrate against the OpenAPI/protocol docs with contract tests, verify the direct_s3 CORS ExposeHeaders: ETag requirement if that transport is on the roadmap, and time-box a spike that exercises resume-after-reload, cancel, and checksum mismatch.
For executives: This replaces a custom large-file upload subsystem — the kind of plumbing that consumes three to six engineering weeks and still ships with edge-case bugs — with an MIT-licensed package we install and control. It removes "large uploads fail on bad connections" as a support category and as a conversion leak, and it launches with no new infrastructure: no queue worker, no websocket service, no capacity spend. If volume grows, the scaling path (queued assembly, direct-to-S3) is a configuration change, not a rewrite — so we are not pre-paying for scale we don't have.
For engineering: Small, typed backend on ports & adapters (PHPStan max), strict TypeScript frontend, one state machine with database and filesystem tracker drivers sharing a contract and a test suite. Sync/queue/auto assembly modes, streaming assembly that never buffers the whole file, typed error codes (checksum_mismatch, lock_timeout, upload_expired) for retry logic, 404-not-403 on non-owner status/cancel to prevent ID enumeration, sanitized and versioned broadcast payloads, chunky:cleanup for scheduled hygiene, and an OpenAPI-documented protocol. Integration surface is a profile class: rules(), directory(), authorize(), completed().
The honest risk statement: the package is young — single maintainer, zero dependents, zero stars, so no crowd-sourced hardening. We mitigate by treating it as fork-ready internal code: MIT license, pin the version, vendor the source, run chunky:doctor in CI, and keep protocol-level contract tests so we can patch or replace it without a client migration. That converts the risk from "dependency on an unknown vendor" to "a component we own with a head start."
How can I help you explore Laravel packages today?