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

Piper Laravel Package

spatie/piper

Piper is a pipe operator-first PHP utility library that ports Laravel’s array and string helpers into standalone functions. Chain filter, map, join, lower, replace, and more with the |> operator, mixing array and string primitives in one clean pipeline.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit Piper is a zero-coupling utility library: pure functions in, closures out, no service provider, no config, no container resolution, no facades. For a Laravel codebase that is architecturally the cheapest possible dependency to absorb — it adds no bootstrapping surface, no lifecycle hooks, and no global state. The design is a deliberate port of Collection/Stringable semantics onto primitives, so it slots in as a complement to Eloquent/Collection rather than a replacement: you exit the Collection world with ->all(), run the pipeline, and re-enter with Str::of() or collect() if the caller expects a fluent object.

The genuine architectural value is composability outside the framework context — named domain pipelines (format_winning_numbers(array $numbers): string) are pure functions of primitives, testable with plain assertions and no DB or container. That is a real win for jobs, console commands, mail/notification body builders, form request prepareForValidation, report row assembly, and CSV normalization.

Integration feasibility Feasibility is gated entirely on one binary fact: PHP 8.5. The |> pipe operator does not exist below 8.5, so composer require spatie/piper will fail platform resolution outright. This is not a soft constraint you can work around with a polyfill. Four things must be verified in order before a decision:

  1. Local php -v and config.platform.php in composer.json.
  2. The CI matrix — PHPStan and Psalm must also parse |> , so they must run on 8.5.
  3. The deploy image base and any shared-hosting or managed-runtime constraints.
  4. IDE/static-analysis tooling support for the operator.

If PHP 8.5 is not already funded and shipping, this package is a no-go today regardless of its merits. If it is, installation is one command with zero registration.

Technical risk

  • Platform risk (high). PHP 8.5 is bleeding-edge. Adopting a library that requires it couples your dependency graph to a runtime upgrade schedule you may not control, especially if any deploy target (legacy host, partner integration, CI runner) lags.
  • Maturity risk (high). 57 stars, 0 dependents, first release 1.0.0, current 1.1.0. This is a brand-new package with effectively no production field data. The changelog so far is export-ignore hygiene and a sortByMany callable addition — nothing that signals a battle-tested API surface.
  • Vendor risk (moderate, mitigated). Spatie is a highly reputable maintainer with a strong OSS track record, which materially lowers abandonment risk. But this is a convenience utility, not core infrastructure, and Spatie's support model for OSS is best-effort community, not contractual.
  • Ergonomics risk (moderate). Function-level imports are weaker than method calls for IDE find-usages, rename refactors, and autocompletion. use function group imports also silently fall back to the global namespace on omission — a class of bug that method chaining structurally cannot produce.
  • Performance risk (low-moderate). Fully eager; each stage materializes an intermediate array. Fine for reports and notifications, wrong for large imports or hot paths.
  • Semantic drift risk (low). Because it is a direct port of Laravel semantics, developer expectations mostly transfer — but "mostly" is doing work in that sentence, and PORT.md documents what was and wasn't ported.

Key questions

  • Is PHP 8.5 shipped in production, in CI, and in static analysis — not merely available locally?
  • What does the pilot diff actually buy us versus the existing collect() chain? Is the readability gain real enough to justify a second idiom in the codebase?
  • Do we have a house rule for when pipes are permitted, or will adoption drift into three idioms per file?
  • Who owns the app/Support/pipes.php seam, and is it reviewed like a public API?
  • What is the exit cost if the package stalls or PHP 8.5 rollout reverses?

Integration Approach

Stack fit Strong for Laravel/PHP shops. The API is a 1:1 port of Collection and Stringable methods, so Laravel-fluent developers already know roughly 90% of the surface; the docs are for confirming names and checking which methods were ported. The natural home is app/Support/pipes.php for named domain pipes, plus targeted use in console commands, job handle payload shaping, mail/notification builders, form request normalization, and seeders/fixtures. It does not belong in models, Blade templates, config, or middleware.

Migration path There is no migration — this is strictly additive. The correct motion is a single-method rewrite, not a sweep:

  1. Pick one existing 3+ step transformation written as a collect() chain or a run of temp variables.
  2. Rewrite it as one PR.
  3. Let code review decide whether the diff reads better.

The canonical before/after is a filter→map→values chain with nested string transforms. Good pilots: report/export builders, notification body assembly, CSV import normalization in a queued job, small artisan utilities. Bad pilots: hot loops, anything protected by LazyCollection, Blade.

Compatibility

  • Runtime: PHP 8.5 mandatory, non-negotiable.
  • Laravel: framework-agnostic in practice; no version coupling to Laravel itself.
  • Static analysis: validate before standardizing. Run one real pipeline through existing PHPStan/Psalm configs and the CI image. Some rule sets need use function-aware configuration, and the analyzer itself must run on 8.5.
  • IDE: expect weaker find-usages and rename support on use function imports. Budget for it in the style guide.
  • Interop: any native function whose subject is the first parameter composes via first-class callable syntax — $values |> array_sum(...). Note this is a different form from |> array_sum(), which evaluates eagerly and breaks.

Sequencing

  1. Gate check — confirm 8.5 across local, config.platform.php, CI matrix (including analyzers), and deploy image. Stop here if any fail.
  2. Spike — one pilot pipeline, one PR, reviewed on readability alone.
  3. Tooling validation — run the pilot through PHPStan/Psalm and the CI image before any style-guide language exists.
  4. House rule — write it down at the same time as the pilot, not after: pipes for three or more transformation steps over primitives; loops or collect() for hot paths, two-step transforms, and anything needing laziness.
  5. Establish the seam — create app/Support/pipes.php with the first two or three named domain pipes and custom curried helpers (round_to, limit_words, tap_pipe).
  6. Broaden — expand only after the pilot has survived a release cycle.

Keep the Collection boundary deliberate: convert at the top and bottom of a pipe, once, explicitly — never mid-pipe.

Operational Impact

Maintenance Low ongoing effort for the library itself: MIT, no config, no migrations, no bootstrapping, no upgrade scripts. The maintenance burden that does exist is self-inflicted and lives in two places — the house style guide, and app/Support/pipes.php, which should be reviewed like a public API because it becomes the de facto extension surface. Dependency hygiene is trivial; the package has essentially no transitive footprint.

Support Community-only via Spatie's GitHub. No SLA, no commercial backing for this specific package. The mitigating factor is Spatie's institutional reputation — abandonment is unlikely to be abrupt — but the bus factor on a 57-star package with two external contributors is genuinely thin. Treat supportability as "we can vendor-fork this in an afternoon if needed," which is true here precisely because the code is small, pure, and MIT.

Scaling Pipelines are eager: every stage builds a full intermediate array, and map adds one closure invocation per element on top of your callback. That is fine for reports, notifications, and per-request payload shaping at normal volumes. It is the wrong tool for a 500k-row import or any high-throughput hot path — benchmark against a plain foreach before use there, and reach for generators or LazyCollection regardless. Scale-out risk is therefore per-call-site, not systemic: the failure mode is one poorly chosen pipeline in a loop, not a library-wide degradation.

Failure modes

  • Wrong operator form. $x |> count() invokes count() with zero arguments and blows up; $x |> count(...) yields a closure. Same trap on dump(): |> dump() pipes null. Highest-frequency week-one bug — mitigate with a custom tap_pipe that guarantees pass-through.
  • Silent global fallback. Omitting the use function import fatals — unless a global of that name exists (your own helper, a polyfill, another package), in which case it silently does the wrong thing. Enforce explicit group imports in review and, ideally, in a lint rule.
  • Key preservation. filter preserves keys exactly like Laravel's. Any filter followed by map-into-arrays, JSON encoding, or other key-sensitive stages needs values() in between.
  • Debuggability cliff. You cannot drop a dd() between stages inside a single expression. The recovery procedure is to explode the pipeline into intermediate variables, isolate the bad stage, then re-collapse — worth documenting so it isn't rediscovered under incident pressure.
  • Platform breakage. A CI image or deploy target silently pinned below 8.5 fails at install, not at test — cheap to detect, but only if the gate check actually runs in CI.

Ramp-up Fast for Laravel developers — the method names are already muscle memory, and the calling convention (config args in, closure out, subject via |>) takes one example to internalize. Realistic estimate: an afternoon to productive, one release cycle to fluent. The two things that need explicit teaching are the |> fn() vs |> fn(...) distinction and the Collection-boundary discipline; both should be in the style guide, not tribal knowledge. The dominant ramp-up cost is not learning Piper — it is the PHP 8.5 upgrade itself, which should be budgeted and sequenced separately and is a prerequisite regardless of whether Piper is adopted.

Verdict for planning purposes: conditional pilot. Fund the PHP 8.5 upgrade on its own merits, not for this library. If 8.5 lands anyway, run one pilot PR with static-analysis validation and a written house rule; defer any broader standardization until the package has a year of field data or internal dependents.

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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow