Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Streams Laravel Package

guzzlehttp/streams

A lightweight PHP library for working with streams, offering object-oriented wrappers, lazy and buffered streams, filtering, limiting, and utility helpers. Once used by Guzzle to power HTTP request and response bodies, it remains useful for composing and manipulating stream data.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Build vs. buy for stream plumbing. This package is the "buy" answer to a recurring question: do we hand-roll chunked reads, buffering, seekability, and temp-file spill logic for large payloads, or do we standardize on a proven PSR-7 StreamInterface implementation? For any team shipping file upload/download, media proxying, CSV/report exports, or log shipping, this is a decision that shows up on the roadmap as "large file handling" and is usually under-scoped.
  • Memory ceiling and unit-cost decisions. Streaming vs. loading into memory is a direct driver of container memory limits, instance sizing, and therefore cloud spend. A stream abstraction is what lets a product decision like "support 2 GB video uploads" or "export 500k-row CSVs" become an infrastructure line item instead of an outage.
  • Feature feasibility for a class of roadmap items: resumable/range downloads, server-side passthrough of third-party assets (signed URLs, CDN offload), S3 multipart uploads, backup/restore pipelines, webhook delivery with large bodies, AI/LLM response streaming to a browser, and progress reporting/telemetry during transfers.
  • API contract decisions. PSR-7's StreamInterface is effectively the industry-standard contract. Committing to it decouples our domain code from a specific HTTP client (Guzzle, Symfony HttpClient, Laravel's Http facade), which preserves the option to swap transports later without a rewrite — a real architectural hedge, not a nice-to-have.
  • Integration scope for Laravel specifically. Laravel's HTTP client is a Guzzle wrapper, Storage/Flysystem surfaces streams, and response()->streamDownload() is the idiomatic egress path. This package sits underneath all three, which means the decision is less "adopt a library" and more "acknowledge the layer you're already depending on transitively."
  • Roadmap guardrail: lifecycle risk. The package is archived and scores low on opportunity. That is itself a decision input — it argues for pinning the successor (guzzlehttp/psr7, which absorbed this functionality) rather than adding a new direct dependency, and for putting "replace abandoned transitive dependencies" on the platform/tech-debt roadmap.
  • Not supported: this is not a product differentiator, not user-visible, and not a source of competitive advantage. It should never consume roadmap capacity as a feature; it belongs in platform hygiene.

When to Consider This Package

Consider it when:

  • You are maintaining a legacy Laravel/Guzzle application pinned to Guzzle 5-era constraints, where guzzlehttp/streams is already present transitively and you need to understand, patch, or fork behavior (e.g., CachingStream, PumpStream, NoSeekStream, LazyOpenStream, AppendStream, or the fopen-style StreamWrapper).
  • You need to vendor or fork a small, MIT-licensed, dependency-free stream implementation for an air-gapped or compliance-constrained build, and you accept the maintenance burden of owning it.
  • You want a reference implementation while designing your own internal abstraction, or while writing tests against PSR-7 stream semantics (seekability, eof, getContents vs read, __toString idempotency).
  • You are auditing supply chain and license posture — MIT, no runtime dependencies, well-understood surface area are all favorable for a compliance review.

Look elsewhere when (the default case):

  • Any new build. Use guzzlehttp/psr7, the maintained successor that contains this functionality. Adding an archived package to a greenfield composer.json is an unforced error.
  • You need asynchronous or event-loop streaming (ReactPHP, AMPHP, Swoole/Octane-aware pipelines) — different abstraction, different backpressure model.
  • You want framework-idiomatic handling: Laravel's Http::withOptions(['stream' => true]), response()->streamDownload(), Storage::readStream(), or Symfony HttpClient's own streaming API. Adding this package directly buys you nothing over what's already installed.
  • You want storage or filesystem semantics — Flysystem owns that layer; S3/GCS SDKs own multipart and resumability.
  • You need active security response. Archived means no patches; if your threat model requires CVE response on every dependency, this fails.
  • Note that dependents show as 0 and the project is archived — treat that as a signal that the ecosystem has consolidated around psr7, not as an invitation.

Decision rule: adopt the interface (Psr\Http\Message\StreamInterface), not this package. If the package is already in the tree, confirm the maintained successor is what's actually resolving.

How to Pitch It (Stakeholders)

For executives (one paragraph): This is a low-level, MIT-licensed library that lets our application move large data — uploads, downloads, exports, media, backups — in small chunks instead of loading it all into memory. It is not a feature; it is a cost and reliability control. The relevant business decisions are memory sizing (direct cloud spend), the size ceiling on files customers can move through our product, and whether we can add streaming AI/download experiences without a re-architecture. Two caveats worth thirty seconds of attention: the package is archived, and the correct move is to depend on its maintained successor, guzzlehttp/psr7, which we almost certainly already pull in transitively via Guzzle. So the recommendation is no new vendor, no new spend, no new risk — just a deliberate confirmation that we're on the maintained path and a small tech-debt item if we're not.

For engineering (the substance):

  • Don't add this dependency. It's archived; its Stream, StreamDecoratorTrait, CachingStream, PumpStream, BufferStream, LazyOpenStream, and StreamWrapper live on in guzzlehttp/psr7. Confirm with composer why guzzlehttp/streams and remove any direct requirement.
  • Code against StreamInterface, not against Guzzle. That keeps us portable across Guzzle, Symfony HttpClient, and future transports, and makes streaming testable with in-memory streams.
  • Watch the known footguns: non-seekable bodies (retries and redirects silently break — wrap or check isSeekable()), __toString() only returning from the current position, unclosed handles leaking file descriptors under Octane, and temp-disk exhaustion from CachingStream/php://temp spill.
  • Laravel specifics: Guzzle is underneath Http; reach the PSR-7 body via $response->toPsrResponse()->getBody(). Use streamDownload/readStream rather than get() on large payloads. Under Octane, stream lifetimes outlive requests — close explicitly.
  • Measurement plan before/after: peak RSS on the 95th-percentile payload, p95 time-to-first-byte, error rate on transfers over 100 MB, temp-disk utilization, and egress cost. If those don't move, the abstraction isn't earning its place.
  • Ongoing ownership: add an abandoned-dependency check to CI (composer audit, Packagist abandoned flags) so this class of risk surfaces on a schedule rather than during an incident.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource