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

Filament Feature Flags Laravel Package

stephenjude/filament-feature-flags

Filament Feature Flags is a Filament plugin for managing Laravel Pennant feature flags from your admin panel. Create and toggle flags, define scopes and conditions, and roll out features per user, team, or custom segment without code changes. Integrates with Filament resources and dashboards.

View on GitHub
Deep Wiki
Context7

Getting Started

composer require stephenjude/filament-feature-flags

php artisan vendor:publish --tag="filament-feature-flags-migrations"
php artisan migrate

If you want durable flag state, also publish Pennant’s migrations and switch its driver to database; Pennant’s default cache store is not a good fit for flags managed from an admin panel.

Register the plugin in your Filament panel provider:

use Stephenjude\FilamentFeatureFlags\FilamentFeatureFlagsPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->plugin(FilamentFeatureFlagsPlugin::make());
}

Define your first feature with Pennant in a service provider:

use Laravel\Pennant\Feature;

Feature::define('new-checkout', fn (User $user) => $user->isBetaTester());

Then open the Feature Flags resource in Filament, create/enable the flag or segment, and evaluate it in application code:

if (Feature::for($user)->active('new-checkout')) {
    // show the new flow
}

Where to look first:

  • The package config file: navigation, models, resource behavior.
  • The FeatureFlagResource and any segment relation manager: this is the day-to-day UI.
  • app/Providers/AppServiceProvider.php: where your Pennant feature definitions live.
  • Laravel Pennant docs: scoping, rich values, caching, and testing rules still apply.

A good first use case is an internal beta: define the feature, create a segment for staff or a specific plan, enable it through the Filament UI, verify with a real test user, then widen the rollout.

Implementation Patterns

  • Keep feature definitions in code and use Filament as the control plane. Pennant’s Feature::define should be the source of truth for resolution; the admin UI should toggle or segment that feature.
  • Use rich values for variants, not just booleans:
Feature::define('checkout', fn (User $user) => match (true) {
    $user->isInternal() => 'v2',
    $user->plan === 'pro' => 'v2',
    default => 'v1',
});
  • Always pass the scope explicitly in jobs, commands, APIs, and tests:
Feature::for($user)->active('new-checkout');

Do not rely on auth()->user() inside queued work; there may be no authenticated user at runtime.

  • Use segments for cohort rollouts and global toggles for kill switches. Keep segment conditions aligned with indexed columns such as plan, role, country, or tenant ID.
  • Centralize flag reads behind a small service so defaults and fallbacks are consistent:
final class Flags
{
    public static function checkout(User $user): string
    {
        return Feature::for($user)->value('checkout') ?? 'v1';
    }
}
  • In Blade, use Pennant’s @feature directive where it fits; for route-level gating, use middleware or policies rather than scattering checks.
  • Typical workflow: define feature → deploy → create flag/segment in Filament → validate with a test user → enable → monitor → remove the flag and dead code. Track cleanup work; feature flags should have a lifespan.
  • In tests, activate flags explicitly and clear Pennant’s cache:
Feature::for($user)->activate('checkout');
Feature::flushCache();
  • Protect the Filament resource. Most teams should not let every panel user toggle production flags; use Filament policies or panel-level access control.
  • In multi-tenant panels, verify that segments use the same tenant key as the application. Global flags can otherwise leak behavior across tenants.

Gotchas and Tips

  • Caching is the biggest footgun. Pennant caches resolutions, so an admin toggle may not reach Octane workers, queue workers, or long-running processes until the cache is flushed. Call Feature::flushCache() after programmatic changes and test with the same cache driver as production.
  • Pennant’s default store is often cache, which is not durable. If flags must survive cache clears, use the database driver and publish Pennant’s migrations. Confirm which tables belong to Pennant and which belong to this package.
  • Feature definitions must run before the admin resource can list them. Avoid deferred providers for Feature::define, and run php artisan config:clear after adding definitions. Stale config caches are a common reason a flag “disappears” from the UI.
  • Segment evaluation depends on the scope object. Feature::active() without an explicit scope may resolve against the current user or a default scope; in console and queue contexts that can be null. Prefer Feature::for($user).
  • Publish tags and class names can change between package versions. Run php artisan vendor:publish interactively to inspect available tags instead of copying old README commands blindly.
  • Do not use feature flags as authorization. A flag is a rollout control, not a security boundary; enforce permissions with policies and gates.
  • Debug with Feature::for($user)->value('flag') in Tinker, inspect the features table and the package’s flag/segment tables, and flush cache before assuming a bug.
  • Remove stale flags and segments. Orphaned rows confuse the UI, and reusing an old feature name can silently reactivate previous behavior.
  • Pin compatible versions of Filament, Laravel, and Pennant. Filament 3 vs 4 and Laravel 10–12 have different plugin/resource APIs; check release notes before upgrading.
  • Extension points: override the resource or model via config, customize navigation and authorization, and use Pennant’s activateForEveryone / deactivateForEveryone for global states. Keep custom evaluation behind an interface so tests can fake it.
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.
jinas/dhivatar
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