nusje2000/feature-toggle-bundle
A Symfony bundle for adding feature toggles to PHP applications. Define toggles in configuration and enable or disable features at runtime, making gradual rollouts, testing, and safe deployment easier without code changes.
Architecture fit
nusje2000/feature-toggle-bundle is a Symfony bundle, not a Laravel package. It ships a Bundle class, DI extension, and Symfony-native configuration tree. The underlying capability (runtime feature flags with strategy/context resolution) is framework-agnostic in concept, but the delivery mechanism is not: Laravel's service container, config repository, and bootstrapping lifecycle differ from Symfony's Kernel/Bundle model. In a Laravel codebase this lands as a third-party dependency requiring an adapter layer, not a drop-in composer install. Fit is therefore rated conditional: viable if we treat it as a library-plus-bridge, poor if we expect native Laravel ergonomics (facades, config/feature-toggle.php, Artisan commands, Octane-safe resolution).
Integration feasibility
Binding the bundle's services into Laravel's container is mechanically possible — Laravel can resolve PSR-11-style services and we can register the toggle resolver as a singleton, then expose a thin facade/helper. The real cost is the configuration layer: the bundle expects Symfony's config tree and parameter bag, so we would hand-roll a translation from config/features.php into whatever array/DTO the resolver consumes. That adapter is our code, our tests, and our upgrade surface. Feasible in days, not hours; not a "composer require and go" story.
Technical risk v6.0.0 is a major release with two breaking changes, both of which have blast radius:
myclabs/php-enum (PR #62). This is the higher-risk item. Any consumer that typed against, extended, or serialised MyCLabs\Enum\Enum instances for toggle names/strategies will break. The likely replacement is native PHP enums, which implies a PHP 8.1+ floor and a change in how enum values are read (->value vs ->getValue()), how they serialise to config/DB, and how they behave under var_export/cache warming. If we persist enum-backed toggle keys or expose them over an API, stored values and JSON shapes may shift.: type and parameter typing on previously untyped methods is a subclassing and decoration hazard. Any custom strategy, decorator, or test double we wrote against v5 signatures can now fatally error on incompatible overrides. Return types are the usual offender — a child method returning null where the parent now declares a non-nullable type is a fatal, not a warning.Secondary risks: a major bump with a two-line changelog and no migration guide or UPGRADE note is a maintainer-signal risk. Small maintainer surface (single primary contributor across both PRs), low ceremony around breaking changes. We should assume we are reading the diff ourselves, not the docs.
Key questions
require), including Symfony version constraints?myclabs/php-enum replaced by native enums, a first-party enum, or removed outright with scalars? This determines our migration mechanics.v5.2.0...v6.0.0 ourselves?Stack fit
Treat this as an unbundled library adoption, not a Laravel package install. The pragmatic pattern: consume the toggle resolution core as a container-managed singleton, expose a narrow internal interface (FeatureToggle::isActive(string $flag, array $context): bool), and let the rest of the app depend only on our interface — never on the bundle's classes. That interface becomes the seam that absorbs the next major bump. If the bundle cannot be cleanly decoupled from Symfony's Bundle bootstrapping, the fallback is to evaluate the underlying toggle library directly or a Laravel-native alternative (Pennant, LaunchDarkly SDK) before committing.
Migration path
composer why-not / composer update --dry-run to surface PHP and Symfony constraint conflicts with our current platform.composer.json only after confirming nothing else relies on it transitively.Compatibility Hard gates to clear before merge: PHP floor alignment with our runtime images, Symfony constraint satisfaction, and a full audit of custom strategies/decorators against the new signatures. Note that any Octane or long-running-worker deployment needs the resolver to be stateless or request-scoped — verify the bundle does not cache context on a singleton.
Sequencing Ship in three stages: (a) adapter + interface with the current version, proving the seam works; (b) upgrade to v6.0.0 behind the seam, with the toggle path covered by tests that assert both enum resolution and typed-strategy behaviour; (c) remove v5 compatibility shims. Do not combine the adapter introduction and the major version bump in one PR — if the upgrade breaks, you will not know whether it was the seam or the version.
Maintenance We now own an adapter layer permanently — that is the true cost of this dependency in a Laravel shop, and it must be resourced. Every upstream release potentially touches our translation code. Budget a recurring slice of each dependency-upgrade cycle for this, and assign a named owner. The two-line v6.0.0 changelog is a warning about future upgrade ergonomics: expect to read diffs, not release notes.
Support Upstream support is community-scale with a concentrated contributor base. Escalation paths are GitHub issues and PRs, with no vendor SLA. For anything on the critical flag-evaluation path (release gating, kill switches), that is an availability risk we must accept explicitly or mitigate by keeping toggle evaluation fail-safe and independently testable.
Scaling Feature toggle reads happen on hot request paths, so resolution cost matters at throughput. Verify the resolver memoises per-request and does not perform config lookups or reflection on every call — reflection-based enum hydration on a per-request basis is a realistic v6 performance concern worth a load test. Under Octane, confirm no cross-request state leakage in the resolver or its cache.
The bigger scaling question is toggle hygiene: without a lifecycle process for retiring stale flags, the toggle set grows unbounded and evaluation cost and cognitive load grow with it. That is a process gap independent of the package, but this dependency does not solve it.
Failure modes
Ramp-up Low conceptual ramp-up — feature toggles are a familiar pattern. The learning cost is concentrated in our adapter, not the bundle: engineers must know to depend on our interface and never on upstream classes, and must know where flag definitions live and how they translate. That needs a short internal doc and a code-review checklist item. Realistically one engineer-day to onboard a mid-level developer, and a half-day of deliberate knowledge transfer so the adapter is not single-owner.
Recommendation: adopt v6.0.0 only via the interface seam and only after the PHP/Symfony constraint check and enum-usage audit clear. If the bundle cannot be decoupled from Symfony bootstrapping, escalate the alternative evaluation (Laravel-native flag tooling) before investing in the adapter — the seam is only worth building if it survives the next major.
How can I help you explore Laravel packages today?