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.13.1(2mo ago)1.3k6.2M—4.1%10620MITPHPPHP ^8.4CI passing

Since Sep 27Pushed 2mo 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 1mo ago

READMEChangelog (10)Dependencies (15)Versions (67)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

75

—

ExcellentBetter than 100% of packages

Maintenance83

Actively maintained with recent releases

Popularity69

Solid adoption and visibility

Community43

Growing community involvement

Maturity90

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

Recently: every ~52 days

Total

62

Last Release

85d 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

[![brendt](https://avatars.githubusercontent.com/u/6905297?v=4)](https://github.com/brendt "brendt (193 commits)")[![freekmurze](https://avatars.githubusercontent.com/u/483853?v=4)](https://github.com/freekmurze "freekmurze (145 commits)")[![mvdnbrk](https://avatars.githubusercontent.com/u/802681?v=4)](https://github.com/mvdnbrk "mvdnbrk (57 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)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (8 commits)")[![patinthehat](https://avatars.githubusercontent.com/u/5508707?v=4)](https://github.com/patinthehat "patinthehat (7 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)")[![lloricode](https://avatars.githubusercontent.com/u/8251344?v=4)](https://github.com/lloricode "lloricode (6 commits)")[![zayedadel](https://avatars.githubusercontent.com/u/7737506?v=4)](https://github.com/zayedadel "zayedadel (5 commits)")[![powellblyth](https://avatars.githubusercontent.com/u/337268?v=4)](https://github.com/powellblyth "powellblyth (5 commits)")[![ciungulete](https://avatars.githubusercontent.com/u/742128?v=4)](https://github.com/ciungulete "ciungulete (5 commits)")[![hailam](https://avatars.githubusercontent.com/u/1132869?v=4)](https://github.com/hailam "hailam (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)")[![romanzipp](https://avatars.githubusercontent.com/u/11266773?v=4)](https://github.com/romanzipp "romanzipp (4 commits)")[![aabadawy](https://avatars.githubusercontent.com/u/63416196?v=4)](https://github.com/aabadawy "aabadawy (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-backup

A Laravel package to backup your application

6.0k21.8M191](/packages/spatie-laravel-backup)[spatie/laravel-health

Monitor the health of a Laravel application

86910.0M83](/packages/spatie-laravel-health)[dyrynda/laravel-model-uuid

This package allows you to easily work with UUIDs in your Laravel models.

4802.8M8](/packages/dyrynda-laravel-model-uuid)[spatie/laravel-sluggable

Generate slugs when saving Eloquent models

1.6k11.5M223](/packages/spatie-laravel-sluggable)[spatie/laravel-schemaless-attributes

Add schemaless attributes to Eloquent models

1.1k8.7M62](/packages/spatie-laravel-schemaless-attributes)[clickbar/laravel-magellan

This package provides functionality for working with the postgis extension in Laravel.

423715.4k1](/packages/clickbar-laravel-magellan)

PHPackages © 2026

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