thinktomorrow/dynamic-attributes
thinktomorrow/dynamic-attributes lets Laravel Eloquent models carry flexible custom attributes without schema changes. Store extra key-value data through a familiar relation, with casting and querying support, so models can be extended dynamically per record.
Architecture fit: The package is a tactical fit for Laravel/Eloquent models that need sparse, user-defined, or locale-specific metadata without schema churn. It is appropriate for CMS content, product attributes, settings, or extension fields where values are read as top-level model attributes. It is a poor fit for core domain entities that require relational integrity, joins, reporting, or high-volume filtering, because the JSON column moves schema governance into application code.
Integration feasibility: Integration appears lightweight—likely a trait/cast/accessor pattern over a JSON column—so initial wiring should be low effort. Feasibility is constrained less by code complexity and more by stack compatibility: the package’s last release was 2020-10-09, so a TPM should require a compatibility spike against the target Laravel, PHP, and database versions before committing.
Technical risk: Risk is high for a foundational dependency. Signals include 10 stars, a score of 0.08, and no release since 2020; this suggests low adoption and low maintenance momentum. Additional risk comes from hidden schema behavior, inconsistent typing, localization fallback ambiguity, JSON query limitations, and indexing constraints. MIT licensing is permissive, but there is no implied support or upgrade path.
Key questions: Which Laravel/PHP/database versions are supported by Composer constraints and CI? Does it work with the target DB’s JSON/JSONB query behavior? How are validation, casting, null/missing keys, and localization fallback handled? What query/filter/sort patterns are supported versus requiring generated columns or application-side filtering? Is the package forkable with tests, and who owns that fork? What is the migration and rollback strategy for existing relational columns?
Stack fit: Best fit is a Laravel application already using Eloquent and a JSON-capable database such as MySQL 5.7+/8 or PostgreSQL. It should be positioned as an application-layer convenience for flexible attributes, not as a replacement for normalized relational modeling. Localization support is valuable only if the team defines locale schema, fallback rules, and editorial workflows up front.
Migration path: Start with a non-critical model or a new table rather than retrofitting a core table. Introduce the package behind a feature flag, keep native casts/accessors as a fallback, and run dual-read validation before switching writes. Backfill existing data with idempotent scripts and explicit type normalization. Avoid mixing package-managed attributes and hand-written JSON mutations in the same column without conventions.
Compatibility: Treat Composer constraints, Laravel version support, PHP version, and database JSON functions as gating checks. Build a small CI matrix covering the target stack and representative queries. If the package is incompatible, prefer a maintained internal fork or a thin native AsArrayObject/custom-cast alternative over forcing an old dependency. Confirm localization behavior against the application’s locale negotiation and fallback requirements.
Sequencing: 1) Run a compatibility and query-pattern spike. 2) Define the JSON schema, validation rules, locale fallback, and indexing strategy. 3) Implement on a pilot model with tests for reads, writes, serialization, and queries. 4) Add observability for malformed data and fallback usage. 5) Roll out to low-risk surfaces, then expand only if query performance and maintainability hold. 6) Document an exit path to a fork or native implementation.
Maintenance: Expect low upstream activity. Pin the version, vendor or fork the package if it becomes important, and assign internal ownership for upgrades and bug fixes. Do not assume future Laravel compatibility will be handled upstream.
Support: Support is community-only with no SLA. The TPM should budget for internal triage, documentation, and regression tests. A small package surface area helps, but stale dependencies can still block framework upgrades.
Scaling: JSON attributes scale acceptably for read-mostly metadata but degrade under heavy filtering, sorting, aggregation, or reporting. Plan generated columns and indexes for common query paths, limit payload size, and avoid application-side filtering over large datasets. Localized attributes can multiply payload size and complicate caching.
Failure modes: Watch for malformed JSON, missing keys silently returning null, type drift between writes, locale fallback errors, mass-assignment exposure, serialization inconsistencies, and query builder behavior that does not understand dynamic attributes. Partial writes and uncontrolled key naming are also risks. Instrument validation failures and fallback usage.
Ramp-up: Basic usage is low-effort for Laravel developers, but correct usage around querying, validation, localization, and schema conventions requires documentation and review. Treat it as a scoped utility with guardrails, not a default modeling primitive.
How can I help you explore Laravel packages today?