$ lexprog.com

// notes from an old coder -- php, databases, and the occasional rant

[September 08, 2025] Laravel

Laravel Pennant: Feature Flags

Laravel Pennant: Feature Flags

────────────────────────────────────────────────────────

Laravel Pennant: Feature Flags

Tip: Define Feature

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

Gotcha: Feature Check

if (Feature::active('new-dashboard')) {
    // Show new dashboard
}

Tip: Feature for Specific Users

Feature::forUser($user)->active('new-dashboard');

Gotcha: Feature in Blade

@feature('new-dashboard')
    <x-new-dashboard />
@else
    <x-old-dashboard />
@endfeature

Tip: Stored Features

'driver' => 'database',

Persist feature flags in the database for per-user control.

Gotcha: Feature Resolution

Features are resolved per-request. Changing a feature mid-request doesn't affect already-resolved checks.

Tip: Use route:cache Carefully

php artisan route:cache is fast, but it doesn't work with closure-based routes. Every time you cache routes, Laravel serializes them. If you have Route::redirect() or closure callbacks, the cache breaks. Stick to controller-based routes in production.

Tip: Model APP_KEY Rotation

Rotating APP_KEY invalidates all encrypted data — cookies, encrypted DB columns, and password reset tokens. If you must rotate (e.g., after a leak), plan a migration that re-encrypts existing data with the new key.

Gotcha: Local Scope Leaks

Global scopes defined in booted() apply to ALL queries on that model — including relationships. An innocent User::all() in admin panel might exclude soft-deleted users if a global scope is active.

Senior Insight

Feature flags are essential for continuous deployment, but they introduce complexity that most teams underestimate. I've seen flags accumulate over months, with dead code paths that nobody remembers how to remove. My practice: pair every feature flag with a cleanup ticket created at the same time, assigned to the same developer. When the flag is enabled in production, the cleanup ticket should be in the next sprint.

Source: Laravel News (https://laravel-news.com/), Freek.dev (https://freek.dev/tags/laravel), Spatie Blog (https://spatie.be/blog)

────────────────────────────────────────────────────────
<-- back to posts