cartalyst/collections
Cartalyst Collections extends Laravel's Collection with a richer set of array helpers, macros, and utilities for filtering, transforming, and manipulating data. It offers convenient methods for everyday PHP workflows, making complex array operations cleaner and more expressive while staying familiar...
Settling build-vs-buy for a commoditized capability — once, in writing. The real decision this package surfaces isn't "should we depend on cartalyst/collections?" It's "where do collection abstractions come from in our codebase?" On Laravel the answer is already made: Illuminate\Support\Collection, LazyCollection, and the Arr helpers ship first-party, are maintained, and carry a release cadence. Use this package as the worked example behind a one-line standard — collection abstractions come from the framework or an actively maintained standalone package; exceptions require an ADR. That rule pays for itself on every future dependency debate at zero feature cost.
Calibrating the dependency scorecard so a version tag is a signal, not proof. The v1.0.0 changelog is a single line — "Added a Collection class" — with no compatibility matrix, no breaking-change notes, no security policy, and no named maintainer. Useful teaching case: a version number is not maintenance; a cadence plus a support commitment is. The fields to re-check before any decision are concrete: tag date, commits in the last 24 months, composer.json PHP constraint, presence of SECURITY.md, named owner. Absent those, "dormant" stands.
Risk-scoring technical debt on the roadmap. The signals — last substantive release 2015-02-18, ~75 stars, 0 known dependents, low opportunity score — read as dormant. A fresh tag doesn't overturn that; at best it's repository housekeeping, at worst it manufactures false confidence for anyone reviewing only the version number. This belongs on the technical-debt register as low-urgency, low-cost-to-contain, and it should never compete with roadmap features for budget.
Containment planning for legacy applications. The only realistic consumer profile is a pre-PHP-7 Cartalyst-era app (Sentinel/Platform lineage) where this arrived transitively. A version reset increases urgency: a re-tagged package can create Composer constraint surprises for anyone pinned to ^0.x or a branch alias. This supports a containment decision — flag as a replacement candidate in the modernization audit, pin the exact version, plan removal rather than upgrade. License isn't the blocker (BSD-3-Clause is permissive and commercially safe); maintenance is.
Supply-chain posture and SBOM input. With no active maintainer and no security patch path, adoption creates a permanent "who fixes this?" question that a fresh tag does not answer — and slightly sharpens, since a 1.0.0 implies a stability guarantee the project has never demonstrated. This feeds dependency-approval gates and the SBOM exception list an actionable row with a named exit criterion.
Sizing the modernization workstream. Every call site migrated, every contract test written, and every adapter seam introduced converts a dormant runtime risk into a one-line binding swap. The PM-level output is a scoped, estimable backlog item rather than an open-ended "clean up dependencies" epic — which is exactly what makes it schedulable.
Consider it only for containment, not adoption. Concretely, when:
illuminate/support, and you would otherwise write the same map/filter loops by hand. Even then, a ~40-line internal helper is usually the cheaper answer.ArrayAccess, Countable, IteratorAggregate drop-in behavior for legacy foreach-heavy methods with minimal edits.Look elsewhere — and by default you should — when:
add/put/forget rather than push/set/forget, no macro(), no higher-order proxies, no LazyCollection, no Arr interop). Copy-pasted Laravel snippets become a reliable source of BadMethodCallException.${var} interpolation are all plausible deprecation sources. That risk has to be spent on a spike before anything load-bearing.SECURITY.md and no maintainer. If the honest answer to "who fixes this when it breaks?" is "nobody," the correct decision is removal, not adoption.->map() returns mixed under PHPStan/Psalm, so you'd be paying for type checking everywhere except where the data actually flows.To executives: This is not a feature investment and it won't consume roadmap capacity. It's a small, contained piece of legacy plumbing that arrived transitively in an older application. It's permissively licensed, so there's no commercial exposure, but it has had no substantive release since 2015, no named maintainer, and no security response process. The recommendation is to keep it exactly where it is, pin it, and schedule its removal as part of planned modernization at low cost. The strategic value here is the precedent: we write down one rule about where collection behavior comes from, and we stop re-litigating this class of dependency decision on every project.
To engineering: Treat it as a containment target, not a tool. New code uses collect(). Existing code touching Cartalyst\Collections\Collection gets wrapped behind a small internal interface — convert on entry with new Collection($array), convert on exit with ->toArray(), and never let the type cross a layer boundary. Pin the exact version (1.0.0, not ^1.0); a ^1.0 constraint on a package with no cadence is an unreviewed change to our runtime. Before anything becomes load-bearing, run a one-file spike against our actual PHP target covering chaining, key preservation through filter, count(), iteration, json_encode, and toArray() round-trip. Then capture the semantics we actually depend on — key preservation, sort stability, whether map reindexes — as contract tests. Those tests are the acceptance criteria for the replacement and the only thing standing between us and a silent ordering change in a production report. Sequence the migration: dead code first (free win), direct collect() equivalents next, genuinely unique behavior last as a small owned class rather than a fork. Delete the adapter only after a full release cycle of clean parity. Run composer why cartalyst/collections before touching constraints; if the answer is "we vendor it," vendor it properly — commit it, own it, put it on the SBOM exception list with an exit date.
How can I help you explore Laravel packages today?