gliterd/backblaze-b2
Laravel package that integrates Backblaze B2 cloud storage with the framework's filesystem, so you can upload, store, and serve files through a familiar driver interface with simple configuration and the official B2 SDK.
What the package is. gliterd/backblaze-b2 is a standalone PHP SDK wrapping the Backblaze B2 native REST API (the pre-S3 "B2 Cloud Storage API": b2_authorize_account, b2_get_upload_url, b2_start_large_file, etc.). It is not a Laravel package — there is no service provider, no facade, and no Storage driver. It is a low-level transport client that a Laravel application must wrap itself. Published under MIT, ~81 stars, last tagged release January 2019.
Architecture fit. Moderate at best, and declining. The package occupies the same architectural slot as Laravel's Flysystem/Storage abstraction but sits below it, so adopting it means writing and owning a custom adapter instead of consuming a framework primitive. Two consequences follow. First, every file operation becomes app-specific code (putFile, temporaryUrl, streaming downloads, directory listing) rather than the one-line Storage::disk('b2')->put(...) surface the rest of the codebase already speaks. Second, the application becomes coupled to B2's proprietary API rather than an S3 dialect, which forecloses multi-vendor portability for object storage — a meaningful loss given how commoditized the S3 API is.
Integration feasibility. Technically straightforward, organizationally awkward. The SDK is plain Guzzle-based PHP, so the plumbing works: bind a configured client into the container, inject it, call it. No exotic extensions, no daemon, no compiled dependency. The friction is everything around the call site — file upload handling, queueing of large multipart uploads, retention/versioning semantics, and signed-URL generation all become bespoke. Rough estimate: 1–2 weeks of engineering for a competent Laravel developer to reach parity with a first-class Flysystem disk, plus ongoing ownership.
Technical risk. High, concentrated in three areas:
s3 disk driver consumes with roughly six lines of config. The package's core value proposition — "the way to talk to B2 from PHP" — has been eroded by the platform itself.Key questions to answer before committing.
composer to resolve to an untested combination?Recommendation. Pursue B2 via Laravel's native S3 disk and the vendor's S3-compatible endpoint. Treat gliterd/backblaze-b2 as a fallback only if a specific B2-native capability proves unavailable through the S3 layer and the team accepts ownership of an unmaintained dependency. Default position: do not adopt.
Stack fit. Laravel's filesystem layer is the natural integration point, and it already anticipates this scenario. The recommended shape:
b2 disk using the s3 driver with B2's S3 endpoint, region, key ID, and application key. Set AWS_USE_PATH_STYLE_ENDPOINT=true and AWS_ENDPOINT to the B2 regional endpoint.Storage::disk('b2') throughout the application — identical API to local and S3 disks, so tests can swap in a fake disk.If the native SDK is required, the fit is still workable but must be architected deliberately: a thin B2Storage service behind an interface, bound in a service provider, registered as a custom Flysystem adapter so the rest of the app keeps speaking Storage. The critical discipline is that no controller, job, or model touches the SDK directly — otherwise the replacement cost when we migrate off it balloons.
Migration path. Phased, with the escape hatch preserved:
s3 disk, run a smoke test covering upload, download, signed temporary URL, existence check, and delete. Timebox to days. This resolves the biggest open question cheaply.FileStorage interface. Existing local-disk code migrates to this seam with no behavior change.b2, verifying checksums. Copy before cutover; leave the source intact for a rollback window.gliterd/backblaze-b2 in Phase 2 without disturbing Phases 3–4. This is precisely why the abstraction seam matters: it converts a hard architectural decision into a reversible implementation detail.Compatibility. Two things to verify explicitly. First, dependency resolution — the 2019 release pins are likely to conflict with current guzzlehttp/guzzle and league/flysystem majors; expect to either accept an old Guzzle or fork and patch. Second, Laravel version — Flysystem 1.x to 3.x was a breaking rewrite, and a package that predates it will not slot in as a v3 adapter without work. Sizing this as "a few days" would be optimistic; size it as engineering-owned work.
Sequencing. Do the S3-endpoint spike before any commitment to the native SDK. If the spike passes, the native SDK never enters the dependency tree and the sequencing collapses to standard disk migration. If it fails, we have lost days rather than weeks and have concrete evidence for a build-vs-adopt decision. Parallel-track the abstraction work (Phase 2) either way, since it is valuable regardless of which backend wins.
Maintenance. This is the dominant cost and it is open-ended. An unmaintained dependency in the storage path means the team inherits: PHP/Laravel upgrade compatibility, Guzzle security patches, and B2 API drift. Realistically that is a "vendor it into the repo and own it" decision, not a "add one line to composer.json" decision. Budget ongoing ownership — even if small in a quiet quarter, it is a perpetual line item and a single point of failure, since the person who wrote the adapter is the only one who understands it. The S3-compatible route shifts this maintenance to Laravel's first-party driver and AWS's SDK, both actively maintained.
Support. No upstream support channel. No issue triage, no security advisories, no maintainer response. When something breaks in production at an inconvenient hour, the resolution path is "read the source and the B2 API docs ourselves." For a storage dependency — the layer that holds customer files — that is a materially worse support posture than the alternative, where the S3 path is documented by both Backblaze and Laravel and has a large body of community troubleshooting behind it.
Scaling. The SDK itself will not be the bottleneck; B2's throughput and per-bucket rate limits will be. Two scaling notes apply to either route. Large files should use B2's multipart/large-file path (supported by both routes) with uploads offloaded to queued jobs so web requests do not hold connections open. Signed-URL generation should be done at render time, not persisted, so URL expiry does not surprise the front end. The native SDK is marginally more direct for B2-specific large-file semantics; the S3 layer exposes the same capability through the standard multipart API. Neither is a decision driver at typical application scale.
Failure modes. Plan for these explicitly, as they differ by route:
Ramp-up. Low technical ramp-up, meaningful organizational ramp-up. Any Laravel developer can use Storage::disk('b2') productively on day one; there is nothing new to learn. The native SDK requires reading its source and B2's API documentation to be productive, plus the adapter design work, plus a reviewer who can validate the auth and multipart logic — realistically a named owner rather than a team skill. Given the package's age, the bus factor is the real ramp-up concern: knowledge will concentrate in one or two people, and it will be knowledge about a dependency the rest of the industry has moved past.
Bottom line for the roadmap. The S3-compatible route delivers the same product outcome — cheap object storage behind Laravel's Storage facade — with lower build cost, lower ongoing ownership, and a credible support story. Adopting this SDK only makes sense if a B2-native capability proves genuinely inaccessible through the S3 layer, and even then it should be wrapped behind an interface so it can be removed later. Decision owner: platform/backend lead. Decision needed before the next storage-touching epic, not during it.
How can I help you explore Laravel packages today?