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.
Str::of() chains, and one-off collect() pipelines. Piper is MIT, Spatie-maintained, and ports Laravel's own collection/string semantics, so the realistic alternative is not "build this" but "keep hand-rolling it." Frame adoption as standardize on an existing idiom rather than add a dependency.|> doesn't exist; Composer resolution fails). Adopting it converts the PHP 8.5 upgrade from "hygiene" into "unlocks a tooling improvement," which is a useful forcing function — or, read the other way, adoption is gated entirely on an upgrade the org must already have funded for its own reasons. Don't let Piper be the justification for a risky runtime jump.prepareForValidation, artisan utility) and ship it as one PR. Decision criteria afterwards: does the diff read better in review? Low cost of being wrong — one file reverts.collect() for Eloquent-centric or lazy paths; plain loops for hot paths. Left unwritten, the predictable outcome is three idioms in one file — which is worse than either idiom alone.Collection, you know 90% of this" is a true statement you can put in an onboarding doc. Modest but real recruiting/retention value for Laravel-specialist teams.LazyCollection.Adopt (or pilot) when all of these hold:
|>), config.platform.php, and your deploy base image.collect() chains, nested helpers, or sequential temp variables — i.e., there's a real surface area to improve.use function group imports before they enter a style guide (function imports weaken find-usages, rename refactors, and autocomplete relative to method calls).composer require and it's done.Look elsewhere when any of these hold:
Collection/Stringable-shaped end to end. The value proposition is primitive-in, primitive-out pipelines with explicit conversion seams at the boundaries. If everything is already object-chained and consistent, you'd be buying a second idiom, not removing one.LazyCollection are the answer there regardless.dd() between stages (|> dump() evaluates eagerly and pipes null; |> dump(...) is required, and even then return-value semantics bite). Teams that debug primarily by inserting dumps mid-expression will feel this as friction, not improvement.One-liner for executives: A free, MIT-licensed readability upgrade for our PHP data-transformation code — adopted with one Composer command, no infrastructure, no vendor contract — but it only switches on once we're on PHP 8.5. Cost: roughly one engineer-week to pilot and document. Risk: low and reversible.
For engineering leadership: The package adds zero new capability — everything it does today is already possible with collect() and Str::of(). What it buys is a standardized, linear, top-to-bottom expression of multi-step array/string transforms, which shows up as faster review, cleaner diffs, and easier onboarding in exactly the files that are hardest to read (report builders, exports, notification bodies, import normalization). Because it's a pure-primitives library, its output is trivially unit-testable with plain assertions — no container, no database.
The honest caveats to state up front, not after the fact:
collect() for Eloquent/lazy; loops for hot paths) and review for it. Without that, we'll end up with a third idiom alongside the two we already have — a net readability loss.Recommendation: Approve a bounded pilot — one existing 3+ step transformation, one PR, one measured before/after read in review — contingent on the PHP 8.5 upgrade already being funded. Defer the style-guide mandate and any broader rollout until the pilot clears and static analysis is verified on 8.5. Do not treat this as a reason to accelerate the runtime upgrade.
How can I help you explore Laravel packages today?