PHPackages                             spatie/laravel-model-states - 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. [Database &amp; ORM](/categories/database)
4. /
5. spatie/laravel-model-states

ActiveLibrary[Database &amp; ORM](/categories/database)

spatie/laravel-model-states
===========================

State support for Eloquent models

2.14.1(2mo ago)1.3k7.2M↓28.6%10620MITPHPPHP ^8.4CI passing

Since Sep 27Pushed 1w ago18 watchersCompare

[ Source](https://github.com/spatie/laravel-model-states)[ Packagist](https://packagist.org/packages/spatie/laravel-model-states)[ Docs](https://github.com/spatie/laravel-model-states)[ Fund](https://spatie.be/open-source/support-us)[ GitHub Sponsors](https://github.com/spatie)[ RSS](/packages/spatie-laravel-model-states/feed)WikiDiscussions main Synced 4d ago

READMEChangelog (10)Dependencies (30)Versions (69)Used By (20)

 [   ![Logo for laravel-model-states](https://camo.githubusercontent.com/85cce45f7105de88113a466426476e43348b4c50c34f95bff9207c4157671f93/68747470733a2f2f7370617469652e62652f7061636b616765732f6865616465722f6c61726176656c2d6d6f64656c2d7374617465732f68746d6c2f6c696768742e77656270)  ](https://spatie.be/open-source?utm_source=github&utm_medium=banner&utm_campaign=laravel-model-states)Adding state behaviour to Eloquent models
=========================================

[](#adding-state-behaviour-to-eloquent-models)

[![Latest Version on Packagist](https://camo.githubusercontent.com/d65ef4168432fb9fb06b1f40c76e3bf72ed39cc6eb9742cc9dcfcba5673431ae/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7370617469652f6c61726176656c2d6d6f64656c2d7374617465732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/spatie/laravel-model-states)[![Run tests](https://github.com/spatie/laravel-model-states/actions/workflows/run-tests.yml/badge.svg)](https://github.com/spatie/laravel-model-states/actions/workflows/run-tests.yml)[![Check & fix styling](https://github.com/spatie/laravel-model-states/actions/workflows/php-cs-fixer.yml/badge.svg)](https://github.com/spatie/laravel-model-states/actions/workflows/php-cs-fixer.yml)[![Total Downloads](https://camo.githubusercontent.com/ba462a6f3d85de6b5dd75066eafe8e6639710c3072426c030457c6b45f262bb2/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7370617469652f6c61726176656c2d6d6f64656c2d7374617465732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/spatie/laravel-model-states)

This package adds state support to models. It combines concepts from the [state pattern](https://en.wikipedia.org/wiki/State_pattern) and [state machines](https://www.youtube.com/watch?v=N12L5D78MAA).

It is recommended that you're familiar with both patterns if you're going to use this package.

To give you a feel about how this package can be used, let's look at a quick example.

Imagine a model `Payment`, which has three possible states: `Pending`, `Paid` and `Failed`. This package allows you to represent each state as a separate class, handles serialization of states to the database behind the scenes, and allows for easy state transitions.

For the sake of our example, let's say that, depending on the state, the color of a payment should differ.

Here's what the `Payment` model would look like:

```
use Spatie\ModelStates\HasStates;

class Payment extends Model
{
    use HasStates;

    protected $casts = [
        'state' => PaymentState::class,
    ];
}
```

This is what the abstract `PaymentState` class would look like:

```
use Spatie\ModelStates\State;
use Spatie\ModelStates\StateConfig;

abstract class PaymentState extends State
{
    abstract public function color(): string;

    public static function config(): StateConfig
    {
        return parent::config()
            ->default(Pending::class)
            ->allowTransition(Pending::class, Paid::class)
            ->allowTransition(Pending::class, Failed::class)
        ;
    }
}
```

Here's a concrete implementation of one state, the `Paid` state:

```
class Paid extends PaymentState
{
    public function color(): string
    {
        return 'green';
    }
}
```

And here's how it is used:

```
$payment = Payment::find(1);

$payment->state->transitionTo(Paid::class);

echo $payment->state->color();
```

Support us
----------

[](#support-us)

[![](https://camo.githubusercontent.com/64c77058de222d1cba14dca09a97ecebdfacb7d8881cb7dff45feb2f75017201/68747470733a2f2f6769746875622d6164732e73332e65752d63656e7472616c2d312e616d617a6f6e6177732e636f6d2f6c61726176656c2d6d6f64656c2d7374617465732e6a70673f743d31)](https://spatie.be/github-ad-click/laravel-model-states)

We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us).

We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards).

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

[](#installation)

You can install the package via composer:

```
composer require spatie/laravel-model-states
```

You can publish the config file with:

```
php artisan vendor:publish --provider="Spatie\ModelStates\ModelStatesServiceProvider" --tag="model-states-config"
```

This is the content of the published config file:

```
return [

    /*
     * The fully qualified class name of the default transition.
     */
    'default_transition' => Spatie\ModelStates\DefaultTransition::class,

];
```

Usage
-----

[](#usage)

Please refer to the [docs](https://spatie.be/docs/laravel-model-states/v2/01-introduction/) to learn how to use this package.

Testing
-------

[](#testing)

```
composer test
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

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

[](#contributing)

Please see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details.

Security
--------

[](#security)

If you've found a bug regarding security please mail  instead of using the issue tracker.

Credits
-------

[](#credits)

- [Brent Roose](https://github.com/brendt)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

78

—

ExcellentBetter than 100% of packages

Maintenance93

Actively maintained with recent releases

Popularity70

Solid adoption and visibility

Community46

Growing community involvement

Maturity91

Battle-tested with a long release history

 Bus Factor2

2 contributors hold 50%+ of commits

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 ~38 days

Total

64

Last Release

74d ago

Major Versions

0.1.0 → 1.0.02019-09-27

1.9.1 → v2.x-dev2020-12-04

v1.x-dev → 2.0.12020-12-09

PHP version history (4 changes)0.1.0PHP ^7.2

1.9.1PHP ^7.2|^8.0

v2.x-devPHP ^7.4|^8.0

2.12.2PHP ^8.4

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/7535935?v=4)[Spatie](/maintainers/spatie)[@spatie](https://github.com/spatie)

---

Top Contributors

[![freekmurze](https://avatars.githubusercontent.com/u/483853?v=4)](https://github.com/freekmurze "freekmurze (149 commits)")[![mvdnbrk](https://avatars.githubusercontent.com/u/802681?v=4)](https://github.com/mvdnbrk "mvdnbrk (57 commits)")[![brendt](https://avatars.githubusercontent.com/u/6905297?v=4)](https://github.com/brendt "brendt (12 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (10 commits)")[![rubenvanassche](https://avatars.githubusercontent.com/u/619804?v=4)](https://github.com/rubenvanassche "rubenvanassche (9 commits)")[![Nielsvanpach](https://avatars.githubusercontent.com/u/10651054?v=4)](https://github.com/Nielsvanpach "Nielsvanpach (9 commits)")[![bjrnblm](https://avatars.githubusercontent.com/u/2300511?v=4)](https://github.com/bjrnblm "bjrnblm (8 commits)")[![AdrianMrn](https://avatars.githubusercontent.com/u/12762044?v=4)](https://github.com/AdrianMrn "AdrianMrn (8 commits)")[![patinthehat](https://avatars.githubusercontent.com/u/5508707?v=4)](https://github.com/patinthehat "patinthehat (7 commits)")[![lloricode](https://avatars.githubusercontent.com/u/8251344?v=4)](https://github.com/lloricode "lloricode (6 commits)")[![A909M](https://avatars.githubusercontent.com/u/119125167?v=4)](https://github.com/A909M "A909M (6 commits)")[![fmeccanici](https://avatars.githubusercontent.com/u/34302839?v=4)](https://github.com/fmeccanici "fmeccanici (6 commits)")[![zayedadel](https://avatars.githubusercontent.com/u/7737506?v=4)](https://github.com/zayedadel "zayedadel (5 commits)")[![ciungulete](https://avatars.githubusercontent.com/u/742128?v=4)](https://github.com/ciungulete "ciungulete (5 commits)")[![powellblyth](https://avatars.githubusercontent.com/u/337268?v=4)](https://github.com/powellblyth "powellblyth (5 commits)")[![aabadawy](https://avatars.githubusercontent.com/u/63416196?v=4)](https://github.com/aabadawy "aabadawy (4 commits)")[![hailam](https://avatars.githubusercontent.com/u/1132869?v=4)](https://github.com/hailam "hailam (4 commits)")[![romanzipp](https://avatars.githubusercontent.com/u/11266773?v=4)](https://github.com/romanzipp "romanzipp (4 commits)")[![maartenpaauw](https://avatars.githubusercontent.com/u/4550875?v=4)](https://github.com/maartenpaauw "maartenpaauw (4 commits)")[![masterix21](https://avatars.githubusercontent.com/u/6555012?v=4)](https://github.com/masterix21 "masterix21 (4 commits)")

---

Tags

eloquentlaravelstatesspatiestate

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/spatie-laravel-model-states/health.svg)

```
[![Health](https://phpackages.com/badges/spatie-laravel-model-states/health.svg)](https://phpackages.com/packages/spatie-laravel-model-states)
```

###  Alternatives

[spatie/laravel-permission

Permission handling for Laravel 12 and up

12.9k102.4M1.4k](/packages/spatie-laravel-permission)[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M346](/packages/psalm-plugin-laravel)[spatie/laravel-medialibrary

Associate files with Eloquent models

6.1k43.2M633](/packages/spatie-laravel-medialibrary)[spatie/laravel-health

Monitor the health of a Laravel application

87512.0M167](/packages/spatie-laravel-health)[laravel/ai

The official AI SDK for Laravel.

1.0k3.2M203](/packages/laravel-ai)[simplestats-io/laravel-client

Server-side analytics for Laravel that follows the full funnel from visit to registration to payment, attributed to the channel that drove it. Revenue, MRR, churn and ad-spend profit (ROAS/CAC) per channel. GDPR compliant, ad-blocker proof.

5022.0k](/packages/simplestats-io-laravel-client)

PHPackages © 2026

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