PHPackages                             bengiese22/laravel-pennant-devcycle - 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. bengiese22/laravel-pennant-devcycle

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

bengiese22/laravel-pennant-devcycle
===================================

Laravel Pennant driver for DevCycle.

0.1.0(1mo ago)00MITPHPPHP ^8.2CI passing

Since Apr 14Pushed 1mo agoCompare

[ Source](https://github.com/BenGiese22/laravel-pennant-devcycle)[ Packagist](https://packagist.org/packages/bengiese22/laravel-pennant-devcycle)[ RSS](/packages/bengiese22-laravel-pennant-devcycle/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)Dependencies (10)Versions (2)Used By (0)

Laravel Pennant DevCycle Driver
===============================

[](#laravel-pennant-devcycle-driver)

[![Tests](https://github.com/bengiese22/laravel-pennant-devcycle/actions/workflows/tests.yml/badge.svg)](https://github.com/bengiese22/laravel-pennant-devcycle/actions/workflows/tests.yml)[![Code Style](https://github.com/bengiese22/laravel-pennant-devcycle/actions/workflows/codestyle.yml/badge.svg)](https://github.com/bengiese22/laravel-pennant-devcycle/actions/workflows/codestyle.yml)[![Static Analysis](https://github.com/bengiese22/laravel-pennant-devcycle/actions/workflows/phpstan.yml/badge.svg)](https://github.com/bengiese22/laravel-pennant-devcycle/actions/workflows/phpstan.yml)

A Laravel Pennant driver backed by the DevCycle PHP SDK. Pennant reads DevCycle Variables for feature evaluation; writes are intentionally unsupported (read-only).

Installation
------------

[](#installation)

```
composer require bengiese22/laravel-pennant-devcycle
```

The package is auto-discovered via the service provider. Publish the optional config file:

```
php artisan vendor:publish --tag=devcycle-config
```

Configuration
-------------

[](#configuration)

Add a `devcycle` store to `config/pennant.php`:

```
return [
    'default' => 'devcycle',

    'stores' => [
        'devcycle' => [
            'driver' => 'devcycle',
            'sdk_key' => env('DEVCYCLE_SERVER_SDK_KEY'),
            'default' => false, // default value when a variable is not found
        ],
    ],
];
```

Setting Up Your User Model
--------------------------

[](#setting-up-your-user-model)

Scopes passed to `Feature::for()` must implement Pennant's `FeatureScopeable` and `FeatureScopeSerializeable` contracts and return a `DevCycleUser` instance.

The easiest way is to add the included trait to your User model:

```
use BenGiese22\LaravelPennantDevCycle\Concerns\HasDevCycleFeatureScope;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Pennant\Contracts\FeatureScopeable;
use Laravel\Pennant\Contracts\FeatureScopeSerializeable;

class User extends Authenticatable implements FeatureScopeable, FeatureScopeSerializeable
{
    use HasDevCycleFeatureScope;
}
```

The trait maps `id`, `email`, and `name` to the `DevCycleUser` automatically. If you need custom data (e.g., custom data fields for targeting), override `toDevCycleUser()`:

```
use DevCycle\Model\DevCycleUser;

protected function toDevCycleUser(): DevCycleUser
{
    return new DevCycleUser([
        'user_id' => (string) $this->id,
        'email' => $this->email,
        'name' => $this->name,
        'customData' => [
            'plan' => $this->plan,
            'organization_id' => $this->organization_id,
        ],
    ]);
}
```

Usage
-----

[](#usage)

DevCycle Variable keys map directly to Pennant feature names:

```
use Laravel\Pennant\Feature;

// Boolean check
if (Feature::for($user)->active('checkout-redesign')) {
    // new checkout flow
}

// Get the variable value (strings, numbers, JSON)
$variant = Feature::for($user)->value('onboarding-flow');
```

Writes (`define`, `set`, `activate`, `deactivate`) are not supported and will throw a `BadMethodCallException`.

### Default Values and Type Matching

[](#default-values-and-type-matching)

The `default` value in your Pennant store config serves two purposes:

1. **Fallback** — returned when a variable doesn't exist, the flag is disabled, or the user isn't targeted
2. **Type hint** — the DevCycle SDK uses the default's type to resolve the variable. If the types don't match, the SDK silently returns your default even when the flag exists and is enabled.

```
'devcycle' => [
    'driver' => 'devcycle',
    'sdk_key' => env('DEVCYCLE_SERVER_SDK_KEY'),
    'default' => false, // boolean — will only resolve boolean variables correctly
],
```

For example, if a DevCycle variable is a boolean but your default is a string, the SDK returns the string default — no error, no exception. The flag is invisible.

This means all three of these cases produce identical behavior:

- The flag doesn't exist in DevCycle
- The flag is disabled or the user isn't targeted
- The flag exists but its type doesn't match the default's type

**If your project uses a mix of boolean and string variables**, use `Feature::value()` with an explicit default per-call instead of relying on the store-level default:

```
// Boolean flag — pass a boolean default
$enabled = Feature::for($user)->value('checkout-redesign') ?? false;

// String flag — pass a string default
$variant = Feature::for($user)->value('onboarding-flow') ?? 'control';
```

Management API (optional)
-------------------------

[](#management-api-optional)

The package can proxy DevCycle's Management API for listing and updating features. This is disabled by default.

Enable it in `config/devcycle.php`:

```
'register_routes' => true,
```

### Routes

[](#routes)

MethodURIDescriptionGET`/api/devcycle/features`List featuresGET`/api/devcycle/features/{featureKey}`Get a featurePATCH`/api/devcycle/features/{featureKey}`Update a featureOverride the project key per-request with `?project=other-project`.

### Route Middleware

[](#route-middleware)

By default, routes use the `api` middleware group. **You should add authentication middleware** before enabling routes in production:

```
// config/devcycle.php
'routes' => [
    'middleware' => ['api', 'auth:sanctum'],
    'prefix' => 'api/devcycle',
],
```

### Credentials

[](#credentials)

Set these in `config/devcycle.php` or via environment variables:

VariableDescription`DEVCYCLE_MGMT_CLIENT_ID`OAuth client ID`DEVCYCLE_MGMT_CLIENT_SECRET`OAuth client secret`DEVCYCLE_MGMT_PROJECT_KEY`Default project key`DEVCYCLE_MGMT_API_BASE`API base URL (optional)`DEVCYCLE_MGMT_AUTH_BASE`Auth base URL (optional)OAuth access tokens are cached automatically using Laravel's cache driver.

Testing
-------

[](#testing)

```
composer test        # Run Pest tests
composer analyse     # Run PHPStan (level 6)
./vendor/bin/pint --test  # Check code style
composer ci          # Run tests + analysis
```

License
-------

[](#license)

MIT. See [LICENSE.md](LICENSE.md).

###  Health Score

34

—

LowBetter than 75% of packages

Maintenance89

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity36

Early-stage or recently created project

 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

Unknown

Total

1

Last Release

56d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/e5fd9d921dcb49dfdd3a21f086031bd0d0e60ac4e7ca6bec361bde45582764bc?d=identicon)[BenGiese22](/maintainers/BenGiese22)

---

Top Contributors

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

---

Tags

laravelpennantfeature-flagsdevcycle

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/bengiese22-laravel-pennant-devcycle/health.svg)

```
[![Health](https://phpackages.com/badges/bengiese22-laravel-pennant-devcycle/health.svg)](https://phpackages.com/packages/bengiese22-laravel-pennant-devcycle)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

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

Rapidly build MCP servers for your Laravel applications.

76318.2M110](/packages/laravel-mcp)[api-platform/laravel

API Platform support for Laravel

59156.3k10](/packages/api-platform-laravel)[zidbih/laravel-deadlock

Make temporary Laravel workarounds expire and fail CI when ignored.

954.0k](/packages/zidbih-laravel-deadlock)

PHPackages © 2026

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