Consent

This site uses third party services that need your consent.

Skip to content
Steven Roland

Mastering Feature Flags with Laravel Pennant

Laravel Pennant is a powerful and lightweight feature flag package introduced in Laravel 10. It allows developers to easily implement feature toggles, enabling incremental rollouts, A/B testing, and more flexible development strategies. In this post, we'll explore how to use Pennant and showcase some practical examples.

Getting Started with Laravel Pennant

First, let's install Pennant:

composer require laravel/pennant
php artisan vendor:publish --provider="Laravel\Pennant\PennantServiceProvider"
php artisan migrate

Defining Features

There are two main ways to define features in Pennant:

Using the Feature Facade

In your AppServiceProvider:

use Laravel\Pennant\Feature;
use App\Models\User;

public function boot()
{
    Feature::define('new-dashboard', function (User $user) {
        return $user->isAdmin() || $user->created_at->isAfter(now()->subDays(30));
    });
}

Using Class-Based Features

Create a new feature class:

php artisan pennant:feature NewDashboard

Then define the logic in the class:

namespace App\Features;

use App\Models\User;

class NewDashboard
{
    public function resolve(User $user): bool
    {
        return $user->isAdmin() || $user->created_at->isAfter(now()->subDays(30));
    }
}

Checking Features

You can check if a feature is active in several ways:

// In controllers or other parts of your application
if (Feature::active('new-dashboard')) {
    // Show new dashboard
}
// For class-based features
if (Feature::active(NewDashboard::class)) {
    // Show new dashboard
}
// In Blade templates
@feature('new-dashboard')
    <x-new-dashboard />
@else
    <x-old-dashboard />
@endfeature

Suggested Usages

  • Gradual Feature Rollout

    Roll out a new feature to a percentage of users:

    Feature::define('new-chat', function (User $user) {
        return $user->id % 100 < 25; // 25% of users
    });
  • A/B Testing

    Implement A/B testing for a new UI design:

    Feature::define('new-ui', function (User $user) {
        return $user->id % 2 === 0; // 50% of users see new UI
    });
  • Beta Testing Program

    Allow certain users to access beta features:

    Feature::define('beta-feature', function (User $user) {
        return $user->isBetaTester();
    });
  • Geographic Feature Availability

    Enable features based on user location:

    Feature::define('eu-compliance', function (User $user) {
        return $user->country->isInEU();
    });
  • Feature Toggles in API

    Use feature flags to version your API:

    Route::middleware('auth:api')->group(function () {
        Route::get('/data', function (Request $request) {
            if (Feature::active('new-api-version')) {
                return $this->newApiResponse();
            }
    
            return $this->legacyApiResponse();
        });
    });

Best Practices

  • Use Descriptive Names: Choose clear, descriptive names for your features to make them easily understandable.

  • Keep Logic Simple: Try to keep the feature resolution logic simple and focused.

  • Leverage Scopes: Use Pennant's scoping capabilities to check features for specific models or entities.

  • Clean Up Unused Flags: Regularly review and remove feature flags that are no longer needed.

  • Test Both States: Always test your application with the feature both active and inactive.

Laravel Pennant provides a clean and efficient way to implement feature flags in your Laravel applications. By leveraging its capabilities, you can achieve more flexible, controlled, and testable feature releases. Whether you're implementing gradual rollouts, conducting A/B tests, or managing complex feature sets, Pennant offers the tools to make your development process smoother and more robust.

Remember, feature flags are powerful tools, but they should be used judiciously. Over-reliance on feature flags can lead to complex codebases, so always consider the long-term implications of each flag you introduce.

More posts

Navigating Beliefs: The Quest for True Meaning

Inspired by Chuck Palahniuk's quote, this post explores the challenge of believing in the right things and finding true meaning. It offers insights on critical thinking, questioning beliefs, and the importance of accurate interpretation in our quest for understanding.

Securing Your Laravel API with Passport: A Comprehensive Guide

Laravel Passport provides OAuth2 server implementation for Laravel apps. It offers features like access token issuance, route protection, and scopes. Install Passport, configure your User model, and protect routes with middleware. Use for mobile apps, SPAs, and third-party API access. Follow best practices like configuring token lifetimes and using HTTPS in production.

Embracing Your Potential: The Wings You Were Born With

Inspired by Leslye Walton's metaphorical question about wings in "The Strange and Beautiful Sorrows of Ava Lavender," this post explores embracing one's innate potential. It offers insights on recognizing personal talents and taking action to achieve one's full capabilities.