gaiatools/fulcrum-settings
Fulcrum Settings is a Laravel package for storing and managing application settings in the database, with a simple API, cached reads, and support for runtime configuration changes.
What the package actually is. Despite the "feature flag" framing, gaiatools/fulcrum-settings is best understood as a database-backed settings and dynamic-configuration layer with a rules engine bolted on. The skill reference clarifies the shape: typed key/value settings, an ordered rule list per setting (priority ascending, first match wins, else default, else caller-supplied fallback), scoped resolution (forUser, forTenant), masked/encrypted values, immutable flags, and versioned "setting migrations" written as code. That is a superset of what most Laravel products build as a bespoke settings table plus a config() cache.
Architecture fit. Strong for the roadmap items we already have: per-tenant defaults-and-overrides, admin-editable operational config without a deploy, and enterprise-tier "bring your own policy" behavior. The typed setting accessors and the SettingMigration DSL mean configuration changes ship through the same review and deploy path as code, which is a genuine governance win versus a loose admin CRUD screen. Resolution order is deterministic and explainable, which matters when a support ticket says "why did this customer see the old dashboard."
Integration feasibility. High on the happy path, with one hard gate and one soft gate. Hard gate: v2.0.0 dropped Laravel 11 — the support matrix is PHP 8.3+, Laravel 12/13. Any service still on Laravel 11 is simply blocked, and a PHP 8.3 floor may force an upgrade ahead of our own schedule. Soft gate: the package assumes Eloquent ownership through a polymorphic relation and interacts with Relation::morphMap(), so the resolution of aliased models is load-bearing.
Technical risk. Low-to-moderate, but the failure modes are the bad kind — silent. The v2.0.0/v2.0.1 changelog reads as a hardening pass on the caching and evaluation layer: cache invalidation on committed writes, cache results isolated by evaluation context, Fulcrum context isolated between worker operations, tenancy listener context preserved during worker cleanup, cached results varied only by relevant request inputs, rollout identifiers resolved for authenticatable scopes. Every one of those is a correctness fix in a code path that, when wrong, returns the wrong value rather than an error. That is materially worse than a crash: a feature flag that silently evaluates to false, or a tenant override that silently falls back to global default, is a customer-visible defect with no stack trace. The v2.0.1 morph-map fix compounds this — patch releases do not repair rows already written under a mismatched type.
Key questions to close before sign-off:
settingable_type / settingable_id / key indexed, and what does a scoped resolution cost at our expected setting count?Stack fit. Laravel 12/13, PHP 8.3+, Eloquent, conventional service-provider ergonomics. Additional compatibility surface worth naming: it explicitly supports Laravel Modules, and it has been hardened for long-lived workers (Octane/queue) where context leaks between requests. If we are on Octane, that hardening is a prerequisite, not a nicety.
Migration path. Two distinct journeys:
^2.0.1 — never 2.0.0. The morph-alias fix is the reason the patch exists.SettingsService interface first, implement it with the package, and keep the legacy table readable behind the same interface. This gives us a swap-out path if the vendor relationship sours and lets us migrate settings in risk order (display preferences → notification prefs → tenant limits → anything gating billed entitlements).Compatibility. Verify the tag's composer.json against both our current Laravel major and the next one; we are mid-cycle on framework upgrades and a package that lags a major locks our upgrade window. Apache-2.0 permits an internal fork, which is our fallback if the project stalls.
Sequencing.
SettingMigration + immutable + masked primitives imply config-as-deployable-artifact; if we let the same values be edited live in an admin UI, we have two sources of truth and need a reconciliation rule.Maintenance. Conventional-commit changelog and semantic-release tooling imply a predictable patch cadence and machine-generated notes — good hygiene for a small project. Budget a standing line item to review every patch, not install-and-forget: v2.0.0 and v2.0.1 both landed correctness fixes in caching and context isolation, which tells you the risk concentrates in patches rather than in majors. Add "clear settings cache" to the deploy runbook, and treat the version constraint as pinned-minor rather than caret until we have two clean quarters.
Support. Single-vendor, three-star project. Bus factor is the dominant risk, and it is not mitigated by the changelog. Mitigations: confirm Apache-2.0 for internal fork, confirm the codebase is small enough for one of our engineers to read end-to-end in a week (it should be), and identify a named internal owner before adoption — not after. Do not adopt for anything a customer pays for without that owner named.
Scaling. The read path is database-backed plus cached, so scaling is a cache-hit-rate problem, not a compute problem. Two concerns: masked/encrypted settings add per-read decrypt cost and should be read rarely, not in hot render loops; and cache correctness depends on invalidation firing on committed writes — verify that in staging under concurrent writes, because a stale-flag window during a partial rollout is exactly the scenario operations cares about. This is not appropriate as the substrate for high-volume real-time experimentation; if that need appears, it is a separate platform decision.
Failure modes to plan for, in severity order:
Ramp-up. Expect two to four days for a mid-level Laravel engineer to become productive with the rules engine, migration DSL, and resolution order, plus the same again to internalize the caching and context model. The bundled skill references (targeting rules, migration API, configuration, contracts/events) shorten this materially — the documentation quality is better than the star count would predict, and that is the strongest argument that the project is maintained rather than abandoned.
How can I help you explore Laravel packages today?