php 36 lines · 6 steps

Defining feature flags with Laravel Pennant

A service provider registers feature flags at boot, from simple config toggles to per-user gradual rollouts.

Explained by highlit
1<?php
2 
3namespace App\Providers;
4 
5use App\Models\User;
6use Illuminate\Support\Lottery;
7use Illuminate\Support\ServiceProvider;
8use Laravel\Pennant\Feature;
9 
10class FeatureServiceProvider extends ServiceProvider
11{
12 public function boot(): void
13 {
14 foreach (config('features.simple', []) as $feature => $enabled) {
15 Feature::define($feature, fn () => (bool) $enabled);
16 }
17 
18 Feature::define('new-billing', function (User $user) {
19 if (in_array($user->email, config('features.new_billing.allowlist', []))) {
20 return true;
21 }
22 
23 return match (true) {
24 ! config('features.new_billing.enabled') => false,
25 $user->onTrial() => false,
26 default => Lottery::odds(
27 config('features.new_billing.rollout_percent', 0),
28 100,
29 ),
30 };
31 });
32 
33 Feature::define('beta-dashboard', fn (User $user) => $user->hasVerifiedEmail()
34 && $user->created_at->lt(config('features.beta_dashboard.cutoff')));
35 }
36}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Feature flags belong in a provider's boot method so they're registered once and resolved lazily on demand.
  2. 2Driving flag values from config lets you flip features without touching code or redeploying.
  3. 3Percentage rollouts and allowlists let you ship risky features to a controlled slice of users first.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Defining feature flags with Laravel Pennant — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code