webparking/laravel-type-safe-collection
Webparking's Laravel Type-Safe Collection adds strongly typed collections to Laravel. Define the permitted item class once to get runtime type checks, clearer errors, IDE autocompletion, and safer map/filter operations, keeping collection contents predictable and preventing mixed-type bugs.
Architecture fit. The package is a thin extension of Illuminate\Support\Collection that enforces a single item type at runtime. Architecturally it fits Laravel cleanly: it is composer-installable, likely auto-discovered, and intended to be subclassed as a domain collection (e.g., OrderCollection, LineItemCollection). It slots into service providers, jobs, and domain boundaries without requiring framework changes. Its value is strongest at bounded contexts where collections cross layers and item-type drift causes defects. It does not provide compile-time generics; it complements, rather than replaces, PHPStan/Psalm template annotations.
Integration feasibility. Feasible for small, isolated adoption. The public surface is likely one abstract class plus overridden mutation methods, so integration is a composer require and a subclass. The main constraint is age: the last release was 2020-09-10, targeting the Laravel 6–8 / PHP 7.x era. On Laravel 9+ the package may fail dependency resolution or break against evolved Collection method signatures and return types. MIT licensing makes forking viable.
Technical risk. Moderate to high for a production dependency. Risks: unmaintained code, only 37 stars (limited battle-testing), potential drift from Laravel collection internals, incomplete enforcement if any mutation path (offsetSet, push, prepend, put, merge, map, filter, chunk, when) is not covered, and runtime-only failures. The dependency is small enough to replicate in-house, which lowers strategic risk but also lowers the case for adopting an external package.
Key questions.
composer.json constraints for illuminate/support and PHP?JsonSerializable?Stack fit. Native fit is Laravel 6–8 on PHP 7.2–8.0. If the platform is Laravel 9–11, treat the package as a reference implementation rather than a direct dependency unless we fork and validate it. For modern stacks, a small internal typed collection or DTO-based approach is a safer fit.
Migration path. Do not perform a wholesale replacement of collect(). Introduce typed collections incrementally at domain boundaries and service return types. If adopting, fork the repository, update composer constraints and method signatures for the target Laravel version, add a CI matrix, and publish internally under a controlled package name. If forking is not justified, replicate the enforcement logic internally and retire the dependency.
Compatibility. Verify against the target Laravel version: Collection method signatures and static return types, Enumerable/LazyCollection interactions, offsetSet/offsetGet, macro support, and serialization behavior for jobs and caches. Confirm PHP 8.1+ deprecation cleanliness. Test that map, filter, merge, chunk, and when do not silently downgrade to untyped collections.
Sequencing.
Maintenance. The code footprint is small, but ownership is not zero. An unmaintained 2020 package requires us to track Laravel collection changes, patch compatibility, and own security and dependency updates. Budget a small but recurring maintenance allocation, or eliminate the dependency by internalizing the logic.
Support. Community-only support; no vendor SLA. Documentation and onboarding must be internal. With 37 stars, the bus factor and community response quality are low. MIT license permits a supported internal fork, which is the realistic support model if adopted.
Scaling. Runtime overhead is negligible: per-item type checks on mutation, no additional infrastructure, memory profile comparable to a normal collection. It will not be a throughput bottleneck. The scaling concern is organizational, not technical: broad adoption increases the blast radius of a breaking Laravel upgrade.
Failure modes. Invalid items raise runtime exceptions (likely InvalidArgumentException or TypeError) during request handling, producing 500s if input is not validated at the boundary. Enforcement can be bypassed through uncovered mutation paths or methods returning base collections. Serialization and queue round-trips may lose the typed subclass. Laravel upgrades may break overridden signatures at boot or first use, which is a late and high-impact failure.
Ramp-up. Low for Laravel developers: subclassing a collection is familiar. Moderate for maintainers who must reason about overridden collection internals and upgrade compatibility. Recommend limiting adoption to well-tested domain boundaries, documenting the enforcement contract, and avoiding use in framework-critical or highly dynamic paths until compatibility with the current Laravel version is proven.
How can I help you explore Laravel packages today?