somnambulist/attribute-model
A Laravel package for declarative model attributes: define typed, castable fields on Eloquent models using PHP attributes, with generated accessors, mutators, and validation—so you can add structured metadata without extra tables or boilerplate.
somnambulist/attribute-model is a small, framework-agnostic PHP library that provides a base attribute model plus a type-casting system: you declare PHP 8 attributes on class properties and the library hydrates/casts raw input (typically a database row or a serialized payload) into typed value objects. It was extracted from the author's read-models package, which means it was designed for the read side of a CQRS-ish architecture rather than as a general-purpose DTO/Eloquent utility.
Architecture fit. The library occupies the seam between persistence and domain: raw rows in, typed read models out. That is a genuinely useful seam, and the abstraction is deliberately thin — closer to a declarative hydrator than to an ORM. It will fit cleanly in a hexagonal or layered codebase where read models are plain PHP objects. It will not fit into a codebase that expects Eloquent casts, Symfony Serializer, or spatie/laravel-data semantics; adopting it means adopting a second, parallel typing mechanism.
Integration feasibility. Low friction mechanically: single composer require, PSR-4 autoloading, MIT license, no framework bootstrap required. The real integration cost is architectural, not mechanical — it is a leaf dependency that must be wired by hand into whatever hydration pipeline exists.
Technical risk. This is the dominant concern, and it is severe:
| Risk | Severity | Notes |
|---|---|---|
| Adoption signal | High | 0 stars, 0 dependents. No third-party battle testing, no external PRs, no ecosystem of examples. |
| Bus factor | High | Effectively a single-maintainer, personal-ecosystem package. Abandonment is a question of when, not if. |
| API stability | Medium | Extracted packages often carry an unstable 0.x/1.x line with breaking changes tied to the parent project's needs. Verify versioning history and tag cadence. |
| Support surface | High | No commercial support, no security policy, no LTS commitment, no deprecation policy. |
| Dependency weight | Low–Medium | Likely pulls somnambulist/collection or similar; audit the full transitive tree for PHP version floors and competing utility packages. |
| Functional risk | Low | The problem space (casting scalars/arrays/UUIDs/date-times into typed properties) is well understood and easy to replace or fork. |
The mitigating factor is scope: the library is small and its responsibility is narrow. A competent PHP engineer can read the whole source in an afternoon and fork it if needed. That converts a "vendor risk" into a "maintenance budget" question rather than a "can we even use this" question.
Key questions to resolve before any commitment:
somnambulist/* packages, and are those equally unmaintained?spatie/laravel-data, Symfony Serializer)?Stack fit. Treat this as a domain-layer utility, not a framework integration. In a Laravel codebase, Eloquent stays the write model and source of truth; this library only governs how rows become typed read models. That separation is healthy, but it must be a conscious decision — otherwise you end up with two competing type systems and a team that can't remember which class gets which treatment.
Migration path. Adopt incrementally and adversarially:
^ against upstream. This is cheap now and expensive later.Somnambulist\. That single indirection is what makes the eventual replacement a contained refactor rather than a codebase-wide search-and-destroy.Compatibility. Verify PHP floor, PSR interface alignment, and absence of conflicts with our existing serialization stack. If the team already uses spatie/laravel-data or Laravel's native casts(), adopting this library introduces three overlapping mechanisms — a net negative regardless of the package's quality. Check also for PHP 8.3/8.4 deprecation warnings and attribute-related edge cases.
Sequencing. The order matters: validate → fork → wrap → pilot → expand. The failure mode to avoid is a "quick win" adoption on a critical path before the fork and wrapper exist.
Maintenance. Assume we own this from day one. Budget a nominal recurring cost: dependency-update PRs, PHP-version compatibility patches, and occasional source fixes. The surface area is small enough that this is realistically hours per quarter, not days per month — but it must have a named owner. An unowned fork is worse than an unowned dependency.
Support. There is no support channel, no SLA, no CVE process. We must decide and document our own policy: how we monitor upstream, how quickly we patch, and what our exit criteria are. Security posture is low-risk given the library's role (no network, no I/O, no auth), which is the main reason this is tolerable at all.
Scaling. Runtime cost is reflection-based metadata resolution. In hot paths — high-throughput request handlers, batch importers — ensure metadata is cached per process rather than re-derived per hydration. For typical read-model workloads this is negligible; for bulk pipelines it warrants a benchmark before rollout.
Failure modes to design against:
null without an exception. Mandate strict mode / validation at the boundary if available.composer update and pulls an unvetted upstream tag; pinning the fork is the control.Ramp-up. Low for engineers familiar with Laravel casts or attribute-based mapping — half a day to productive, with the caveat that documentation is likely thin and the source becomes the reference. Budget an internal design note (one page: what we use it for, what we don't, how to add a cast, how to report a bug) and a short brown-bag session. The bigger ramp-up risk is conceptual: the team must understand why two typing mechanisms coexist.
Bottom line. Technically serviceable and structurally sensible, but an orphaned dependency with zero adoption signal. It is defensible only as a forked, wrapped, internally-owned component in a bounded context — and it is not defensible as a direct composer require on any critical path. Before investing, benchmark it honestly against spatie/laravel-data and native Laravel casts; the realistic outcome is that this package is interesting prior art rather than a production dependency.
How can I help you explore Laravel packages today?