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

novaway/feature-flag-bundle

Novaway FeatureFlagBundle is a Symfony bundle for defining and toggling feature flags via configuration, annotations, and Twig. It supports strategy-based activation, gradual rollouts, and safer releases without redeploying.

View on GitHub
Deep Wiki
Context7

Getting Started

First, the honest framing: novaway/feature-flag-bundle is a Symfony bundle, not a Laravel package. There is no service provider, no facade, no Blade directive, and no config/feature-flags.php. If you're in a pure Laravel app, you cannot composer require it and use it day one — you'd be pulling in Symfony DI/Twig contracts for a feature that a 40-line config class could cover. Treat this assessment as "what it does, and how I'd use it" if you're in a Symfony codebase (or a hybrid app where Symfony components are already present).

For a Symfony developer, getting started is genuinely minimal:

composer require novaway/feature-flag-bundle

With Symfony Flex the bundle registers itself; otherwise add it to config/bundles.php. Then create config/packages/novaway_feature_flag.yaml:

novaway_feature_flag:
    features:
        new_checkout:
            enabled: false
            description: "Rewrite of the checkout flow"
        beta_dashboard:
            enabled: true

Where to look first: run bin/console debug:config novaway_feature_flag to confirm your flags parsed, and bin/console debug:container | grep -i feature to find the manager service ID and its exact class/namespace (these have shifted across versions — verify before copy-pasting imports). The bundle's README is short and is effectively the whole API surface.

First use case: gate a single new route or template block behind new_checkout, flip it to true in the dev environment config only, and confirm prod stays dark. That's the entire value proposition: a boolean map in YAML plus a manager service to read it.

Implementation Patterns

Inject the manager, don't scatter getParameter() calls. The manager is the seam you want in tests and the seam you'd swap if you outgrow the bundle:

use Novaway\Bundle\FeatureFlagBundle\Manager\FeatureManager;

final class CheckoutController
{
    public function __construct(private FeatureManager $features) {}

    public function __invoke(): Response
    {
        if ($this->features->isEnabled('new_checkout')) {
            return $this->newFlow();
        }
        return $this->legacyFlow();
    }
}

Twig for view-level toggles. The bundle ships a Twig extension, so templates stay readable:

{% if feature_flag('beta_dashboard') %}
    {% include 'dashboard/beta.html.twig' %}
{% else %}
    {% include 'dashboard/legacy.html.twig' %}
{% endif %}

Environment-scoped rollout is the idiomatic pattern. Because config is static YAML, the cheapest "canary" is per-environment overrides:

# config/packages/prod/novaway_feature_flag.yaml
novaway_feature_flag:
    features:
        new_checkout: { enabled: true }

Combine with Symfony's when@env blocks if you prefer a single file. This is coarse (all-or-nothing per environment) but it's honest and auditable in git — a real advantage over DB-backed flag systems for small teams.

Wrap flags in a domain-named accessor. Rather than sprinkling string literals, define constants or a thin AppFeatures class that delegates to the manager. This gives you IDE navigation and a single place to grep when a flag dies. It also gives you an obvious boundary to replace the package later.

Kill-switch usage. Keep a small set of flags mapped to operational toggles (e.g. disable_third_party_sync) and let ops flip them via config + deploy. Do not use this bundle for anything that needs to change without a deploy — see Gotchas.

Testing. Since the manager is a service, bind a stub in the test container with the flag forced on/off, and write both branches of every gated path. In Symfony, a FeatureManager double with a hardcoded map is usually faster and clearer than loading YAML fixtures.

Laravel integration, if you insist. Don't install the bundle. Port the idea: a FeatureFlags class bound as a singleton, reading config/feature-flags.php, plus a Blade directive @feature('new_checkout'). You'll get the same behavior in ~30 lines with zero cross-framework dependency. The bundle's only real asset is its naming and config shape, which you can copy without the dependency.

Gotchas and Tips

  • It's KISS by design — know the ceiling. No database storage, no admin UI, no percentage rollouts, no user targeting, no audit trail, no expiry. Any flag change requires a config edit and a deploy (or at least a cache clear). If your roadmap includes "enable for 5% of users" or "enable for internal accounts," you will outgrow this quickly.
  • Config cache is the #1 debugging trap. Symfony caches compiled config. After editing flags in prod, bin/console cache:clear (or deploy) is mandatory. A "flag didn't change" bug is almost always stale cache, not the bundle.
  • Default-to-off discipline. The manager's behavior for an undefined flag name is the thing to verify first — write a test asserting what an unknown key returns in your version, then standardize on it. Never let a typo silently enable a feature.
  • Bundle namespace drift. The manager/Twig extension FQCNs and the config root key have varied across releases. Always confirm via debug:container and debug:config rather than trusting a blog post. This is a small package with a short README; the container is the source of truth.
  • Twig extension registration. If you're not using Flex, the extension won't be auto-wired and feature_flag() will throw an unknown-function error. Register the bundle correctly before blaming the template.
  • Vendor risk is real. 25 stars, zero dependents, low opportunity score. It's a thin wrapper — the blast radius of it being abandoned is small because it does so little, but that's also an argument for copying the pattern into your app instead of depending on it. Pin the version and read the diff on upgrade; there's little community to catch regressions.
  • Extension points are thin. The realistic customization is decorating the manager service or replacing the config loader — both are Symfony-standard, not bundle-specific. If you need a custom flag provider, you're writing it yourself anyway.
  • Don't let flags become permanent. Because there's no expiry metadata, dead flags accumulate invisibly. Adopt a convention (e.g. every flag's description includes a ticket ID and target removal date) and audit the YAML monthly. The bundle won't do this for you.
  • Config file is your audit log. This is the bundle's underrated strength: every flag change is a git commit. Lean into it — review flag changes in PRs the same way you review migrations.
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.
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings