PHPackages                             webrek/laravel-feature-flags - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. webrek/laravel-feature-flags

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

webrek/laravel-feature-flags
============================

Feature flags for Laravel with percentage rollouts, rule-based targeting and A/B variants.

v1.1.0(2d ago)00MITPHPPHP ^8.2CI passing

Since Jun 8Pushed 2d agoCompare

[ Source](https://github.com/webrek/laravel-feature-flags)[ Packagist](https://packagist.org/packages/webrek/laravel-feature-flags)[ Docs](https://github.com/webrek/laravel-feature-flags)[ RSS](/packages/webrek-laravel-feature-flags/feed)WikiDiscussions main Synced yesterday

READMEChangelog (2)Dependencies (9)Versions (3)Used By (0)

Laravel Feature Flags
=====================

[](#laravel-feature-flags)

[![Latest Version on Packagist](https://camo.githubusercontent.com/603f0ae127cab3ef558096afe9a1f182e2aa871c198d7dd9c96e959f875ca5b7/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f77656272656b2f6c61726176656c2d666561747572652d666c6167732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/webrek/laravel-feature-flags)[![Total Downloads](https://camo.githubusercontent.com/ba4f8289fc376e99e142a6e4b0d110fc128e3f3ad62332ae8fe26db96254b6bb/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f77656272656b2f6c61726176656c2d666561747572652d666c6167732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/webrek/laravel-feature-flags)[![Tests](https://camo.githubusercontent.com/10a9162895eb55a5bf053e874c344f1501794801e7218e329991a9d921296950/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f77656272656b2f6c61726176656c2d666561747572652d666c6167732f74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/webrek/laravel-feature-flags/actions/workflows/tests.yml)[![PHP Version](https://camo.githubusercontent.com/13b4a3bf968105a699cf1be4f5b9a6e9d7141d31955a4ad2e01df1dbc9714248/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f77656272656b2f6c61726176656c2d666561747572652d666c6167732e7376673f7374796c653d666c61742d737175617265)](https://php.net)[![License](https://camo.githubusercontent.com/4fff86557cbbf2a48666f6197b85302d2a86319ae33b1cc99716a3d211ccbdd9/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f77656272656b2f6c61726176656c2d666561747572652d666c6167732e7376673f7374796c653d666c61742d737175617265)](LICENSE)

Feature flags for Laravel with **percentage rollouts**, **rule-based targeting**and **A/B variants** — flip features at runtime without a deploy.

Quickstart
----------

[](#quickstart)

```
composer require webrek/laravel-feature-flags
php artisan vendor:publish --tag=feature-flags-migrations
php artisan migrate
```

```
use Webrek\FeatureFlags\Facades\Features;

// Define a feature rolled out to 25% of users:
Features::create('new-checkout', rollout: 25);

// Check it (defaults to the authenticated user):
if (Features::active('new-checkout')) {
    // ...
}

// Or for a specific scope:
Features::for($user)->active('new-checkout');
```

```
@feature('new-checkout')

@endfeature
```

Why not roll your own boolean column
------------------------------------

[](#why-not-roll-your-own-boolean-column)

A `boolean` column on a settings table answers one question: is this on for everyone? Real feature work needs more:

- **Gradual rollout.** Ship to 5% of users, watch your metrics, raise it to 25%, then 100% — and a user who was in the 5% stays in as you climb, because bucketing is deterministic, not random per request.
- **Targeting.** "Enterprise plans only", "users in MX and US", "accounts older than 30 days" — expressed as constraints, not branches scattered through code.
- **A/B variants.** Assign each user a stable variant (`blue` vs `green`) and measure which converts.
- **Runtime control.** Flip a flag from the database or an artisan command without a deploy, and kill a misbehaving feature instantly.

This package does all of that, and unlike Laravel Pennant it stores rollouts, constraints and variants as data you can manage — not just closures in code.

Defining features
-----------------

[](#defining-features)

With the database store (the default), define and manage at runtime:

```
Features::create(
    'enterprise-export',
    active: true,
    constraints: [
        ['attribute' => 'plan', 'operator' => 'in', 'value' => ['pro', 'enterprise']],
    ],
);

Features::create('button-color', variants: [
    ['name' => 'blue',  'weight' => 50],
    ['name' => 'green', 'weight' => 50],
]);

Features::activate('new-checkout');
Features::deactivate('new-checkout');
Features::rollout('new-checkout', 50);
Features::forget('old-flag');
```

Or declare them in code with the **array store** (great for tests or simple apps) — set `FEATURE_FLAGS_STORE=array` and fill `config/feature-flags.php`:

```
'features' => [
    'new-checkout' => ['active' => true, 'rollout' => 25],
    'button-color' => ['active' => true, 'variants' => [
        ['name' => 'blue', 'weight' => 50],
        ['name' => 'green', 'weight' => 50],
    ]],
],
```

Checking features
-----------------

[](#checking-features)

```
Features::active('new-checkout');             // default scope (auth user)
Features::active('new-checkout', $user);       // explicit scope
Features::inactive('new-checkout', $team);
Features::variant('button-color', $user);      // 'blue' | 'green' | null
Features::for($user)->active('new-checkout');  // fluent

feature('new-checkout');                       // helper, returns bool
feature();                                      // helper, returns the manager
```

A feature resolves to **active** only when every gate passes: the master switch is on, the scope matches all constraints, it falls within the rollout percentage, and (for a variant feature) a variant is assigned.

Scopes
------

[](#scopes)

Pass anything as a scope:

- **`null`** (or omit) — the authenticated user, falling back to a global scope.
- An **Eloquent model** — bucketed by class + key; its attributes feed targeting.
- Anything implementing **`FeatureScope`** — you control the identifier and the attributes exposed to constraints.
- A **string or int** — used directly as the bucketing identity.

```
use Webrek\FeatureFlags\Contracts\FeatureScope;

class Team extends Model implements FeatureScope
{
    public function featureScopeIdentifier(): string
    {
        return 'team:' . $this->id;
    }

    public function featureScopeAttributes(): array
    {
        return ['plan' => $this->plan, 'seats' => $this->seats];
    }
}
```

Targeting constraints
---------------------

[](#targeting-constraints)

Each constraint is `['attribute' => ..., 'operator' => ..., 'value' => ...]` and all must pass. Supported operators:

`=` · `!=` · `in` · `not_in` · `>` · `>=` · ` 'plan', 'operator' => 'in', 'value' => ['pro', 'enterprise']],
    ['attribute' => 'seats', 'operator' => '>=', 'value' => 10],
]
```

Blade &amp; middleware
----------------------

[](#blade--middleware)

```
@feature('new-dashboard')

@endfeature

@unlessfeature('new-dashboard')

@endfeature
```

```
Route::get('/beta', BetaController::class)->middleware('feature:new-dashboard');
// 404 unless the feature is active for the current user
```

Artisan
-------

[](#artisan)

```
php artisan feature:list
php artisan feature:activate new-checkout
php artisan feature:deactivate new-checkout
php artisan feature:rollout new-checkout 50
```

Dashboard
---------

[](#dashboard)

A built-in web UI to toggle features, adjust rollout, and create or delete flags at runtime — no deploy, no database client. It is server-rendered (no JS build, no CDN) and lives at `/feature-flags` by default.

```
// config/feature-flags.php
'dashboard' => [
    'enabled' => env('FEATURE_FLAGS_DASHBOARD', true),
    'path' => 'feature-flags',
    'middleware' => ['web'],
],
```

> The dashboard controls your flags, so protect it. Add auth/authorization middleware (e.g. `['web', 'auth', 'can:manage-features']`) and, in production, restrict who can reach it. It manages the active store, so use the database store. Publish the views to customise them:

```
php artisan vendor:publish --tag=feature-flags-views
```

Requirements
------------

[](#requirements)

ComponentVersionPHP8.2+Laravel12.xTesting
-------

[](#testing)

```
composer install
composer test
```

Contributing
------------

[](#contributing)

See [CONTRIBUTING.md](CONTRIBUTING.md).

Security
--------

[](#security)

Please review the [security policy](SECURITY.md) before reporting a vulnerability.

License
-------

[](#license)

The MIT License (MIT). See [LICENSE](LICENSE).

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance99

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity47

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

2d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/7d8deca81629993819087597b5ad7695976b02e3d014f038e26e985f35f569de?d=identicon)[webrek](/maintainers/webrek)

---

Top Contributors

[![webrek](https://avatars.githubusercontent.com/u/5001338?v=4)](https://github.com/webrek "webrek (4 commits)")

---

Tags

ab-testingfeature-flagsfeature-togglelaravellaravel-packagephprolloutlaravellaravel-packagefeature toggletogglerolloutfeature-flagsexperimentsab-testingtargeting

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/webrek-laravel-feature-flags/health.svg)

```
[![Health](https://phpackages.com/badges/webrek-laravel-feature-flags/health.svg)](https://phpackages.com/packages/webrek-laravel-feature-flags)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3325.1M337](/packages/psalm-plugin-laravel)[laravel/ai

The official AI SDK for Laravel.

9782.1M153](/packages/laravel-ai)[spatie/laravel-health

Monitor the health of a Laravel application

88011.3M149](/packages/spatie-laravel-health)[api-platform/laravel

API Platform support for Laravel

59156.3k10](/packages/api-platform-laravel)[laracraft-tech/laravel-useful-additions

A collection of useful Laravel additions!

58122.8k](/packages/laracraft-tech-laravel-useful-additions)[calebdw/larastan

Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel

15104.9k4](/packages/calebdw-larastan)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
