enhavo/metadata
Metadata component for the Enhavo content framework, providing models and services for storing, resolving, and rendering resource metadata such as titles, descriptions, and SEO-related attributes across pages.
Architecture fit
enhavo/metadata is not a Laravel package. It is a component of Enhavo, a Symfony-based CMS, published as a [READ-ONLY] subtree split of a larger monorepo. It is Composer-installable in any PHP project, which is why it surfaces in Laravel-adjacent tooling, but installability is not fit.metadata table, model observers).Integration feasibility
Technical risk
| Risk | Severity | Program impact | Owner of the check |
|---|---|---|---|
| Symfony/Doctrine coupling | High | Blocks direct use in Laravel; forces fork or reimplementation | Eng lead, source audit |
| Maintenance / bus factor | High | Single-vendor project; split publishing depends on monorepo CI we don't control | TPM, vendor diligence |
| Undocumented public API | Medium | Ramp-up cost lands on us; no external docs to lean on | Eng, spike phase |
| Stale release cadence | Medium | PHP/Symfony version drift breaks us silently on upgrade | Eng, Packagist check |
| Storage/serialization behavior | Medium | If metadata blobs round-trip through unserialize(), potential object-injection surface |
Security review |
| Schema ownership | Medium | If the package owns migrations, upstream change can desync our DB with no changelog | Eng, audit |
Key questions to resolve before any commitment
composer.json constraints on PHP, Symfony components, and Doctrine, and do they collide with Laravel's pinned Symfony versions?main branch, or is the split stale?These are one engineer's half-day of work and should gate every subsequent decision. Do not let a spike start before they are answered.
Stack fit
metadata tables, JSON casts, attribute casting, model observers, eager loading. The package's semantics transfer; its code likely does not.Options, ranked
| Option | What it means | Effort | Risk | When to choose |
|---|---|---|---|---|
| 1. Reimplement natively (default) | Extract the interface and value-object semantics; rebuild as a small internal Laravel package behind our own contract | ~1–2 eng-weeks incl. tests | Low | Unless the audit finds non-trivial logic worth preserving |
| 2. Vendor / fork | Copy relevant source into packages/, retain MIT header, own it outright |
~3–5 eng-days + permanent ownership | Medium | If the implementation encodes real logic (validation, inheritance, merging) |
| 3. Consume directly | composer require and wire it up |
~2–3 eng-days | High | Only if the package is genuinely Symfony-free — confirm via composer.json and use statements across src/ |
Compatibility and migration path
Sequencing
composer.json, src/, and any tests. Answer the six questions above. Nothing else starts until this lands.The sequencing matters more than the timeline: the audit is cheap, the fork is not, and the gate is what prevents a team from drifting into permanent ownership by accident.
Maintenance
Support
Scaling
Failure modes
| Failure | Likelihood | Impact | Mitigation / detection |
|---|---|---|---|
| Upstream abandonment or monorepo restructure | Medium over 24mo | Pinned version keeps working but gets no security or PHP-compat updates | Pin explicitly; monitor Packagist release dates quarterly |
| Dependency conflict on Laravel upgrade | Medium–High if consumed directly | Resolution often impossible without forking mid-upgrade | Avoid direct consumption; isolate behind our own interface |
unserialize() surface with user-influenced input |
Unknown until audited | Object-injection vector | Security review in the audit phase, before any use |
| Silent schema drift | Low if we own schema; High if we don't | DB desyncs from code with no changelog warning | Own the migrations; never let the dependency own tables |
| Knowledge concentration | High | Single internal owner = real handover risk | Write internal docs during the audit; pair a second engineer |
Ramp-up
Program recommendation
Do not put this on the roadmap as a standalone dependency. The adoption signals — zero stars, zero dependents, no description, no independent release process, read-only mirror — do not support it as anything we would defend in a review. Treat it as a reference implementation and a source of design vocabulary for a native Laravel metadata model. Fund the two-day audit to confirm that conclusion, keep the decision memo, and revisit only if the organization formally evaluates Enhavo as its CMS. If Enhavo is not the CMS, this should never enter our stack.
How can I help you explore Laravel packages today?