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 Flags Filament Laravel Package

liberusoftware/feature-flags-filament

A Filament admin panel integration for managing feature flags. Browse, toggle, and configure flags from a dedicated Filament resource, giving teams a simple UI to control feature rollouts without touching code or config files.

View on GitHub
Deep Wiki
Context7

Getting Started

Treat this as a Filament presentation layer over Liberu's feature-flag domain package, not a standalone flag engine. You will almost certainly need the core feature-flags module installed and configured first; this package only supplies the Filament plugin, resource/page, and UI for toggling flags.

Minimal setup:

composer require liberusoftware/feature-flags-filament

Verify the dependency chain before writing code:

composer show liberusoftware/feature-flags-filament
composer show liberusoftware/feature-flags   # or module-feature-flags

Then publish and migrate:

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

Register the plugin in your panel provider:

use Liberu\FeatureFlagsFilament\FeatureFlagsFilamentPlugin; // verify exact FQCN in src/

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugins([
            FeatureFlagsFilamentPlugin::make(),
        ]);
}

Where to look first, in order:

  1. composer.json — Filament major-version constraint, core module dependency, PHP version, autoload namespace.
  2. src/ — the plugin class and service provider. This tells you the real class names, publish tags, and whether migrations live here or in the core module.
  3. config/feature-flags-filament.php — navigation group, resource registration, tenancy, authorization hooks.
  4. resources/views/ — whether the UI is a custom page, a resource, or a widget.
  5. README.md and tests/ — the only reliable documentation for an unstarred package.

First use case: create a flag named new-dashboard in the Filament UI, then gate a resource or navigation item:

public static function shouldRegisterNavigation(): bool
{
    return Feature::active('new-dashboard');
}

If Feature is not the facade name in your core module, check the core package's src/Facades directory before copying snippets.

Implementation Patterns

Register flags in code, toggle them in the UI. The Filament screen is an operator interface, not the source of truth. Define flags in an enum or config file and sync them to the database:

enum Flags: string
{
    case NewDashboard = 'new-dashboard';
    case BetaBilling = 'beta-billing';
}

Then seed or sync:

foreach (Flags::cases() as $flag) {
    FeatureFlag::firstOrCreate(['name' => $flag->value]);
}

Avoid letting operators create arbitrary flag names in production; that is how you get typo-flagged dead code.

Gate Filament surface area with closures, not boot-time checks. Filament evaluates visibility at render time when you use closures, which means a flag toggle can take effect on the next request:

Resource::make()
    ->visible(fn () => Feature::active(Flags::BetaBilling->value));

TextInput::make('vat_number')
    ->visible(fn () => Feature::active('eu-vat'));

Action::make('recalculate')
    ->disabled(fn () => ! Feature::active('new-billing-engine'));

For whole resources, canAccess() and shouldRegisterNavigation() are the correct hooks. Do not conditionally call ->resources([...]) based on a flag unless you accept that the panel's component cache must be cleared on every toggle.

Wrap flag checks in a cached service. A flag check per row, per field, or per navigation item becomes a query per check if the adapter reads from the database. Centralize:

class Flags
{
    public function active(string $flag): bool
    {
        $tenant = Filament::getTenant()?->getKey() ?? 'global';

        return Cache::remember(
            "flag:{$tenant}:{$flag}",
            now()->addMinutes(5),
            fn () => Feature::active($flag)
        );
    }
}

Invalidate in an observer on the flag model, and key the cache by tenant if you use Filament tenancy.

Use the UI for environment-specific overrides, not for permanent decisions. A common workflow: flags default to false in config, QA enables them through the Filament panel, and production enables them only after release. Record who toggled what — if the package does not ship an audit log, add an observer on the flag model that writes to your activity log.

Respect tenancy. If your panel uses ->tenant(Team::class), check whether the plugin and the core module scope flags per tenant. If they do not, you must scope them yourself or accept global flags. In a multi-tenant panel, a global flag toggle from one tenant's admin UI is a security and product problem.

Testing pattern. Do not drive the Filament UI in unit tests to flip flags. Seed the flag state directly and use RefreshDatabase:

protected function setUp(): void
{
    parent::setUp();
    FeatureFlag::create(['name' => 'beta-billing', 'enabled' => true]);
    Cache::flush();
}

If the core module exposes a fake or Feature::fake(), use it for pure unit tests; use the database path for integration tests that exercise the Filament resource.

Authorization. Add a policy for the flag resource or a gate in the plugin config so only trusted roles can toggle flags. The default behavior of a Filament resource is "any panel user who can reach it," which is rarely what you want for production flags.

Gotchas and Tips

  • Zero stars, zero dependents, NOASSERTION license. Treat this as vendor code you own. Pin an exact commit or version in composer.json, vendor-review the license with legal, and be prepared to fork. Do not assume upstream fixes.
  • Filament major-version coupling is the most likely breakage. Check the filament/filament constraint in composer.json before upgrading Filament. A plugin built for Filament v3 will not silently work on v4; panel registration and resource APIs changed.
  • Double migrations. The core feature-flags module may already publish the flags table. Publishing this package's migrations too can cause duplicate-table errors. Inspect both packages' migration directories before running migrate.
  • Cache staleness after toggling. The UI writes to the database; your application cache may still hold the old value. Verify whether the package dispatches an event on save. If not, add an observer that flushes flag:* keys.
  • Panel component caching. php artisan filament:cache-components and php artisan optimize can freeze conditional resource registration. If a flag "doesn't work" in production but works locally, clear Filament's caches first.
  • Eager flag checks at boot. Calling Feature::active() inside a service provider's boot() method runs before the database may be available (e.g., during migrate or package discovery). Prefer closures and defer checks to request handling.
  • Per-check query cost. A resource with 30 fields each calling a flag lookup can issue 30 queries. Cache aggressively and key by tenant/environment.
  • Authorization defaults are permissive. Confirm the resource's canViewAny, canCreate, and canUpdate behavior. Add a policy before exposing the panel to non-admin users.
  • Tenant leakage. If flags are global but the panel is tenant-scoped, one tenant's admin can change behavior for all tenants. Test this explicitly with two tenants.
  • Config publish tag names are guesswork until you read the provider. Run php artisan vendor:publish interactively and look for the package's provider to discover the real tags; incorrect tags fail silently.
  • Namespace drift. Liberu packages have used both Liberu\... and module-specific namespaces across versions. Confirm the plugin FQCN from src/ rather than copying from a blog post.
  • Debugging tip. php artisan about shows discovered packages; php artisan filament:about (if available in your Filament version) shows panel plugins. If the plugin does not appear, registration failed before any flag logic ran.
  • Extension points to look for: a configurable resource class, a custom navigation group, a ->using()-style resource override, and any registered widget. If the package exposes a custom page instead of a resource, you can usually replace it via config without forking.
  • Upgrade discipline. Because there is no community pressure on this package, treat every composer update as a code review. Read the diff on src/ and the migrations, not just the changelog.
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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core