Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Feature Flag Bundle Laravel Package

gracious/feature-flag-bundle

A Symfony bundle for managing feature flags in your application. Enable or disable features at runtime, roll out changes gradually, and control access without redeploying code. Integrates cleanly with existing Symfony services and configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony bundle, not a Laravel package. If you are working in a Laravel codebase, stop here — there is no service provider, Blade directive, or config/feature-flags.php integration. The release targets Symfony 7/8 on PHP 8.3+.

Minimal setup:

  1. Install with Composer using the package name from the release (e.g. composer require gracious/feature-flag-bundle). Symfony Flex should register the bundle automatically; otherwise add it to config/bundles.php.
  2. Create the bundle config, typically config/packages/gracious_feature_flag.yaml, and declare your first flag with an enabled boolean and an optional description.
  3. Inject the default manager into a service or controller and check a flag before executing the new code path.

First use case: gate a new checkout or dashboard flow behind a flag, check it in a controller/service for enforcement, and check it in Twig to hide the navigation entry. Look first at the bundle README's config reference, the manager service ID/alias, the Twig function signature, and the #[RequireFeature] attribute class. Confirm exact config keys and service IDs against the release — the notes describe capabilities, not the precise API surface.

Implementation Patterns

Config-driven flags as the source of truth. Define flags centrally with descriptions. Treat descriptions as living documentation for non-developers and keep flag names stable and descriptive (checkout.new_flow, not flag1). Wrap flag names in a small constants class or enum so typos fail at one place rather than scattered string lookups.

Named managers for separate flag groups. Use the default manager for application-wide flags, and named managers for isolated domains (e.g. checkout, admin, experiments). Named managers prevent one team's flag namespace from colliding with another's. Since multiple manager services exist, alias the one you want explicitly in services.yaml or use #[Autowire] — autowiring by type alone will be ambiguous.

PHP service checks as guard clauses. Inject the manager and return early when a flag is off. Keep the check close to the entry point (controller, message handler, command) rather than buried deep in domain logic, so the disabled path is easy to reason about and remove later.

Twig for presentation, PHP for enforcement. Use the Twig check to hide links, menu items, and partials. Never rely on it for access control — always repeat the check server-side.

Route defaults for coarse gating. Attach the flag to a route default so the bundle can enforce access at routing time. This is a good fit for whole pages or admin sections where you want a consistent response when the flag is off, without repeating checks in every action.

#[RequireFeature] for controllers. Prefer the attribute over manual if blocks in controllers. It is declarative, visible in the class signature, and keeps the disabled behavior consistent. Decide deliberately whether a disabled feature should return 404 (hide existence) or 403 (acknowledge but deny), and make that consistent across the app.

Runtime overrides for tests and local debugging. Use per-process enable/disable/reset in test setUp() and always reset in tearDown(). This is the cleanest way to test both branches of a flag without touching config. It is also useful for local CLI experiments.

REST endpoint for observability. The read-only endpoint is for dashboards and ops checks, not for toggling. Keep the kill switch off by default in production, and if you enable it, put it behind your firewall/access_control and restrict it to internal networks.

Gotchas and Tips

  • Symfony/Laravel mismatch. The biggest pitfall is assuming Laravel conventions. There is no Blade @feature, no facade, and no config/feature-flags.php. Use Symfony config, DI, Twig, and attributes.
  • Flags are config-driven, not database-driven. Changing a flag means changing config and deploying (and clearing the config cache in prod). Do not expect runtime toggling from an admin UI. If you need dynamic flags, this bundle is a foundation, not a complete solution.
  • Per-process overrides are not per-request. Under long-running runtimes (FrankenPHP, RoadRunner, Swoole), a runtime override can leak into subsequent requests. Reset after each request via a kernel terminate/reset listener, or avoid runtime overrides in production entirely.
  • Config cache. In prod, flag changes require bin/console cache:clear (or a deploy that rebuilds the container). Flags compiled from env vars will not update without a rebuild; prefer explicit config values for anything you expect to flip.
  • Unknown flag behavior. Check what happens when a flag name is misspelled or undefined — fail loudly in dev, and consider defining defaults so a missing flag cannot silently enable a feature. Add a smoke test that asserts every referenced flag exists in config.
  • Autowiring ambiguity with named managers. When more than one manager exists, bind the intended one explicitly. Otherwise container compilation fails or the wrong group is checked.
  • Attribute vs. security ordering. If both a firewall and #[RequireFeature] apply, confirm which response wins. A disabled feature behind authentication can produce confusing redirects instead of the 404/403 you intended.
  • Kill switch defaults. Verify the REST endpoint route is absent or forbidden by default. Read-only reduces risk but still leaks flag names and states — treat it as internal telemetry.
  • Test hygiene. Always reset overrides in tearDown(), and test both enabled and disabled states for critical paths. A flag that is only tested in the "on" state is a latent production incident.
  • Extension points. If you need audit logging or per-user rollout, decorate the manager service rather than forking the bundle. Keep the decorator thin so upgrades remain easy.
  • Debugging. Add a small console command or internal debug route that dumps all flags and their states per manager; this pays for itself the first time someone asks "why is this page 404ing?"
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle