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

Attribute Model Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

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:

  1. What are the exact PHP version constraints, and do they align with our floor and our upgrade roadmap?
  2. Does it depend on other somnambulist/* packages, and are those equally unmaintained?
  3. What is the test suite's depth and CI posture, and does it run on our target PHP versions?
  4. Does it conflict with, or duplicate, our existing casting/serialization approach (Eloquent casts, spatie/laravel-data, Symfony Serializer)?
  5. What is the actual release history — dates, semver discipline, breaking-change frequency?
  6. How does hydration fail? Exceptions, silent nulls, partial objects? This determines our error-handling design.
  7. Are we prepared to fork and own it internally, and who is that owner?

Integration Approach

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:

  1. Spike first. One engineer, one or two days: build a representative read model against a real payload, exercise edge cases (nullables, nested casts, collections, enums, money, UUIDs). Produce a short written verdict including the source-code line count and the delta against our current approach.
  2. Fork before you depend. Because upstream is effectively unmaintained, vendor the package under our namespace (or hard-fork to an internal repo) at the version we validate. Pin the fork; never ^ against upstream. This is cheap now and expensive later.
  3. Pilot in one bounded context. Pick a read model with stable shape and low blast radius — ideally a reporting or projection path, not a user-facing write path.
  4. Wrap it. Introduce a thin internal adapter so call sites reference our names, not Somnambulist\. That single indirection is what makes the eventual replacement a contained refactor rather than a codebase-wide search-and-destroy.
  5. Expand only on evidence. Broaden adoption only if the pilot reduced code volume and defect rate measurably.

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.

Operational Impact

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:

  • Silent coercion. Values cast to the wrong type or to null without an exception. Mandate strict mode / validation at the boundary if available.
  • Partial hydration. Missing keys producing half-populated objects that fail much later and far away.
  • Upstream drift. Someone runs composer update and pulls an unvetted upstream tag; pinning the fork is the control.
  • Framework evolution. A future Laravel release adds native capability that supersedes this; the internal wrapper makes that swap tractable.
  • Fork decay. Our fork diverges from upstream, and someone eventually attempts an unnecessary re-merge. Document the fork policy explicitly.

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.

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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings