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

Safe Stream Laravel Package

nette/safe-stream

Nette SafeStream provides a stream wrapper for atomic file operations, ensuring files are never left partially written or corrupted. It supports file locking and safe concurrent access, making it ideal for writing configs, caches, and logs reliably in PHP applications.

Deep Wiki
Context7

Technical Evaluation

What it actually is. nette/safe-stream is not a Laravel package — it is a single-purpose PHP primitive that registers a safe:// stream wrapper so native calls (file_put_contents, fopen, rename) become atomic: content is written to a temporary file in the target directory, then rename()d into place. That is the entire value proposition.

Architecture fit. Very narrow, framework-agnostic surface — no service provider, no facade, no config, no Laravel version coupling. It slots in as an infrastructure utility behind your own interface (e.g. AtomicFileWriter) rather than as a filesystem abstraction. It does not compete with Flysystem/Storage; it complements it for the "write-then-read-on-another-request" case where a torn read is a real defect. Fit is good if you have a concrete class of files that must never be observed half-written (compiled caches, generated config, export artifacts, tenant-scoped snapshots).

Integration feasibility. Low effort: one Composer require, one guarded wrapper registration, one adapter class. Constraints are ordinary PHP constraints — the target directory must be writable by the same OS user as the writer, and the temp file must land on the same filesystem/volume as the destination or rename() silently degrades or fails.

Technical risk (ranked).

  1. License is NOASSERTION. This is the gating risk. Nette projects are typically BSD-3-Clause, but the tooling could not confirm it. Do not ship to a commercial or redistribution-adjacent product until legal has manually reviewed the LICENSE file in the actual tree.
  2. Repository: unknown. No verifiable upstream link from the registry metadata. Combined with a release date of 2026-10-28 — a future timestamp — the metadata is unreliable. Treat provenance and release integrity as unverified; pin an exact version and commit hash, and vendor or mirror the source.
  3. Low adoption signal (118 stars, composite score ~20.9). Little third-party scrutiny, no visible security disclosure channel. The code is small enough to audit yourself in an hour — do that rather than trusting the ecosystem.
  4. Stream-wrapper edge cases. Wrapper-layer behavior diverges from plain paths for stat, flock, SplFileObject, ftruncate, and mode handling. It gives atomic replacement, not durability — verify whether it fsyncs before rename; if not, a power loss can still leave you with a truncated outcome on the temp file (harmless) or a lost write (not harmless).
  5. Portability. rename() atomicity does not hold on NFS/EFS/FUSE or object storage. This is a single-node primitive.

Key questions for the maintainer/source review. Confirmed license text and SPDX identifier? Supported PHP range and CI matrix? Windows behavior? Temp-file permissions/ownership inheritance? Failure return semantics (warning + false vs exception)? Any open_basedir or read-only-rootfs handling?

Bottom line. Technically sound and genuinely useful for a narrow problem; commercially blocked until license and provenance are resolved. Do not adopt on the strength of the registry score alone.

Integration Approach

Stack fit. Pure PHP, no framework dependencies, no conflict with existing dependencies. Works on PHP 8.1+ with Laravel 9–12. Use alongside Storage/Flysystem, never as a replacement.

Where to use it — and where not to.

  • Use: compiled view/config caches written by one process and read by another; generated exports and report files; tenant or feature-flag snapshots; any file_put_contents whose target is read by a concurrent request.
  • Do not use: user uploads (use Storage/Flysystem), application logs (Monolog handlers already handle this), anything on object storage, anything on a shared network volume where you need true cross-node consistency.

Wiring. composer require nette/safe-stream with an exact pin. Create an AtomicFileWriter interface in your domain and a thin adapter that calls into safe:// paths. Register the wrapper once, idempotently, guarded by in_array('safe', stream_get_wrappers()), inside a dedicated service provider's register() — never in boot() and never via unguarded package discovery, or you will double-register under Octane and in long-lived workers. If the wrapper or the underlying package is absent, the adapter should fall back to native writes plus a logged warning rather than throwing on boot.

Migration path.

  1. Inventory all file_put_contents, fwrite, fopen('w') call sites.
  2. Rank by blast radius — what breaks if a reader sees a half-written file?
  3. Move the top tier behind AtomicFileWriter only; leave the rest alone. Resist a blanket sweep.
  4. Run a concurrency contract test (one writer, N readers, assert no truncated reads) before promoting beyond the first call site.
  5. Document the fallback path so a future maintainer knows why the indirection exists.

Compatibility checks. Verify behavior across every entrypoint you run — FPM, artisan, queue workers, and Octane — since wrapper registration and temp-file cleanup differ per lifecycle. Check open_basedir, container read-only root filesystems, and whether the web user and queue user share write permission on target directories. Ensure the destination volume is local, not a mounted network share.

Sequencing. Legal/provenance clearance → single-call-site spike → concurrency contract test → gradual rollout behind the interface → docs. Budget roughly one sprint of part-time effort end to end.

Operational Impact

Maintenance. Tiny, stable codebase with low churn and no transitive dependency weight — the ongoing cost is near zero if it passes legal. The offsetting concern is that this is a byproduct of the Nette framework, not a product with a roadmap; feature requests and PHP-version bumps track the parent project's needs, not yours. Vendor lock-in is negligible because the abstraction is one class — you can reimplement it in ~50 lines if the package is ever abandoned.

Support. No commercial support, no SLA, no visible security policy. Incident response is entirely yours. Budget for self-audit of the source and a pinned, mirrored copy so an upstream takedown or repo disappearance is not an outage.

Scaling. Solves single-node write/read races only. It does not address multi-node or multi-container concurrency — horizontal scaling with shared or object storage requires a different mechanism (database advisory locks, object-store conditional writes, or a queue-serialized writer). Syscall overhead per write (temp create + write + rename) is negligible relative to network I/O but is measurable in high-frequency small-write loops; do not use it in a tight hot path.

Failure modes to monitor.

Failure Symptom Mitigation
License unresolved Legal block at release review Gate adoption on manual LICENSE review
Wrapper not registered in one entrypoint Unable to find the wrapper "safe" fatal Idempotent registration in register(), single bootstrap path
Target dir not writable by the executing user Warning + false, callers that ignore returns write nothing Fail loudly in the adapter; alert on false
Cross-device / network filesystem Non-atomic rename, corrupted reads Restrict to local volumes; assert volume in CI
Disk full Orphaned temp files accumulate Sweep stale temp files; monitor inode/disk alarms
Ownership mismatch (FPM vs queue user) 403/500 on read of a successfully written file Shared group + umask check in deploy validation
Octane worker temp-file leaks Slow disk growth in long-lived workers Cleanup on exception in the adapter

Ramp-up. Under a day for a mid-level engineer to read the source, build the adapter, and write the concurrency test. Documentation is sparse but the code is small and legible, so onboarding risk is low; the real onboarding cost is teaching the team when atomic writes matter, which is a design conversation, not a library one.

Overall. Adopt conditionally: valuable, low-cost, narrowly scoped, and safe to reverse — pending license and provenance clearance. If legal cannot confirm the license, replace it with a 50-line internal helper; the functional loss is minimal and the compliance exposure disappears entirely.

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.
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
noith/settings
kda/laravel-package