ongr/settings-bundle
Symfony bundle for managing configurable application settings, with services for storing, retrieving, and editing settings. Integrates with ONGR’s Elasticsearch stack to persist settings and expose them to your application.
Architecture fit — poor, unchanged by v1.0.0. ongr/settings-bundle remains a Symfony bundle, not a framework-agnostic library. Its extension points are Symfony-specific: a Bundle subclass registered in the kernel, DI service definitions in XML/YAML, compiler passes, Symfony Form types for editing, Doctrine-style entity mappings for the settings/values tables, and the Symfony event dispatcher. Laravel's equivalents — ServiceProvider, the type-hint container, config/*.php, Eloquent, Validator, Laravel events — share no interfaces with any of this. A version bump and a new event surface do not create a Laravel boot path; there is still no route where a Laravel app loads this short of embedding a Symfony kernel.
What v1.0.0 changes — modestly, and in our favour conceptually. "Added events" is the one substantive signal. If those are domain events fired on setting write (before/after change, with scope and old/new value), that is exactly the hook a cache-invalidation and audit story needs, and it strengthens the case for copying the domain model rather than the code: model, typed values, defaults overlay, cache decorator, plus a change event. Laravel's event dispatcher can carry the same contract natively in the port. "Stable to release major version" is a SemVer statement, not a support commitment — it says the maintainer intends API stability, not that the project is resourced.
What v1.0.0 does not change. The release notes contain no mention of PHP 8.x support, Symfony 6/7 compatibility, updated Composer constraints, Doctrine annotation-reader migration, or PSR-3/PSR-6 alignment. The original blocker was dependency resolution — 2016-era constraints (PHP 5.5/7.x, Symfony 2.8/3.x) colliding with illuminate/* on PHP 8.1+ — and a release note that says nothing about constraints must be assumed to leave them intact. Until the composer.json is inspected, treat resolution as still blocked.
Technical risk — high, but the risk category has shifted slightly. Previously the dominant risk was abandonment (last release 2016-10-04, ~8 years). A v1.0.0 tag after long dormancy is ambiguous: it can mean a maintainer returning, or a single burst of tidying before the project goes quiet again. Neither reading produces a support guarantee. The structural risks are unchanged — PHP 8 deprecations, dynamic properties, typed-signature drift, Doctrine annotation-reader changes — and the "nobody will fix it" failure mode is now less certain but no less unpriced. Zero dependents and 7 stars still means no ecosystem validation of any combination, including this one. MIT remains the clean part: forking is legally unencumbered, so the question is still who owns the fork.
Key questions before any decision:
composer.json? Specifically PHP floor, Symfony version range, and Doctrine ORM/annotations. This single file decides whether "resolve and try it" is even a spike we can run.config(); runtime is a real feature.Stack fit — do not integrate; reimplement. Recommendation stands. A 1.0.0 tag on a Symfony bundle does not make it a Laravel dependency. Keep the 1–2 week port of the domain model into an Eloquent-backed Laravel package — settings and settings_value tables, a typed cast per value, a SettingsContainer resolving defaults → stored overrides, a Cache::remember decorator with tags or versioned keys, and now a SettingChanged event mirroring whatever v1.0.0 introduced. Before building, still evaluate spatie/laravel-settings: typed settings classes, migrations, encrypted values, maintained. The new release does not alter that build-vs-adopt comparison one bit, because the comparison was never about feature count — it was about framework fit and maintenance. Adopt if it covers the scope model; build only the gaps.
Migration path — move data, not code. Unchanged, since the schema almost certainly did not move (and if it did, verify before running the export):
settings / settings_values tables and document scope-key semantics (what "global" vs. owner-scoped means today).tenant_id / user_id or an explicit scope discriminator) and map old keys onto it.artisan command that exports, transforms, and imports, with a verification pass comparing resolved values for every key.Compatibility. Nothing to pin — the constraint set still blocks resolution on any Laravel ≥ 6 unless v1.0.0 modernised composer.json, which is a 15-minute check, not an assumption. If the old system must stay alive during transition, wrap it: keep the Symfony app as-is, expose a thin settings API, and have Laravel call it through an anti-corruption layer. Budget the extra service, and note the new events make that facade slightly more useful — a settings-change webhook is now plausibly cheap to emit, which helps keep the transitional cache warm.
Sequencing:
composer.json — 30 minutes, decides whether a trial is even possible.spatie/laravel-settings.Maintenance. Mixed signal, marginally better than "abandoned," not good enough to depend on. A v1.0.0 tag after roughly eight years of silence is evidence of a maintainer, not of a maintenance programme: no stated support window, no release cadence, no visible CI or PHP-8 matrix in the notes. Treat any fork as owned code in perpetuity with a named maintainer and review cadence — or decline. Zero dependents still means no external signal when behaviour changes, and the new events add a surface that only we would notice breaking.
Support. No vendor, no living documentation beyond the 2016 README, ONGR docs, and now a two-line release note. Negligible Stack Overflow footprint — and the new event API has essentially zero community examples, so it is effectively undocumented. The realistic 2 a.m. escalation for a broken settings lookup is still an on-call engineer reading Symfony DI and compiler-pass internals. Recurring cost, not one-time.
Scaling. The read path — one DB lookup plus a cache hit — will never be the bottleneck. The scaling risk remains cache invalidation fan-out: per-tenant/per-user settings mean a key per owner and a write that must invalidate precisely the right keys. The new events could improve this if they fire reliably on write with scope in the payload; that is a reason to copy the pattern, not to adopt the bundle. Laravel cache tags or versioned keys handle it natively. Read-heavy: fine. Write-heavy across many tenants: not fine, and unproven either way in the 1.0.0 code.
Failure modes to enumerate and test.
null instead of a declared default, surfacing as a type error deep in business logic.Ramp-up. High and disproportionate for a Laravel team: Symfony 2/3 bundle conventions, DI/compiler passes, and Doctrine annotation mapping must all be learned to change a settings table — plus now the Symfony event dispatcher and the bundle's event contracts, which are the least documented part of the release. A Laravel-native reimplementation is a day of ramp-up; spatie/laravel-settings is an afternoon.
Recommendation. Unchanged: use this package as a design reference only — copy the settings/values/scope/defaults/cache model, and now the change-event pattern, not the code. v1.0.0 is a genuine positive signal and worth 30 minutes of changelog review before dismissing, but "added events" and a SemVer tag do not resolve a framework mismatch, do not demonstrate PHP 8 / Symfony 6 support, and do not create a support obligation. An opportunity score of 3.56 still does not offset an eight-year-dormant Symfony bundle in a Laravel stack, and a 7-star, zero-dependent repo carries no ecosystem validation. Adopt a maintained Laravel-native settings package or fund the two-week port — and if the changelog shows modernised constraints, revisit the build-vs-adopt line, not the adopt-the-bundle line.
How can I help you explore Laravel packages today?