NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Packagist · #1119 most downloaded on Packagist
State support for Eloquent models
Last release 2 months ago
22 Jul 2026
Ships fairly regularly
a new release about every 2 months
Nearly every release is documented
notes for 57 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
7 years old
63 releases · first in 2019
Bump actions/checkout from 6 to 7 by @dependabot [bot] in #309
Full Changelog: 2.14.1...2.14.2
Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.14.1...2.14.2
One column per quarter.
Bump dependabot/fetch-metadata from 1 to 3 by @dependabot [bot] in #305
Full Changelog: 2.14.0...2.14.1
Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.14.0...2.14.1
Fix PHP 8.5 trait binding order bug when state is cast via casts() method by @conorjmurphy in #306
Full Changelog: 2.13.1...2.14.0
Use spatie/php-attribute-reader by @freekmurze in #303
Full Changelog: 2.13.0...2.13.1
Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.13.0...2.13.1
What's Changed Add Laravel 13 support
Update issue template by @AlexVanderbist in #292
Full Changelog: 2.12.1...2.12.2
Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.12.1...2.12.2
feat: add count and boolean methods for available transactions by @WatheqAlshowaiter in #290
Full Changelog: 2.12.0...2.12.1
Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.12.0...2.12.1
Add the field property to StateChanged event by @aabadawy in #286
transitionableStateInstances() method to get state objects for all transitionable states by @A909M in #285Full Changelog: 2.11.3...2.12.0
transitionableStateInstances() method to get state objects for all transitionable states by @A909M in https://github.com/spatie/laravel-model-states/pull/285Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.11.3...2.12.0
Add support for registering states from multiple custom directories. by @A909M in #282
Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.11.2...2.11.3
use laravel [validationRule] interface instead of [Rule] deprecated interface by @aabadawy in #276
Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.11.1...2.11.2
fix(config): var annotation for $baseStateClass and $defaultStateClass by @maartenpaauw in https://github.com/spatie/laravel-model-states/pull/275
$baseStateClass and $defaultStateClass by @maartenpaauw in https://github.com/spatie/laravel-model-states/pull/275Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.11.0...2.11.1
Contract / Interface for Models that use HasStates trait. by @aSeriousDeveloper in https://github.com/spatie/laravel-model-states/pull/274
HasStates trait. by @aSeriousDeveloper in https://github.com/spatie/laravel-model-states/pull/274Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.10.1...2.11.0
Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.10.0...2.10.1
Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.10.0...2.10.1
Added test to ensure same-state transition fails when not allowed by @zayedadel in https://github.com/spatie/laravel-model-states/pull/270
Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.9.0...2.10.0
Feature: Added ...transitionArgs to default transition constructor call to allow arguments use for custom default transition by @IlliaVeremiev in http
Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.8.0...2.9.0
Make using allowAllTransitions() less cumbersome by @jonjakoblich in https://github.com/spatie/laravel-model-states/pull/265
Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.7.2...2.8.0
[docs] Fix documentation badges by @maartenpaauw in https://github.com/spatie/laravel-model-states/pull/254
$allowedTransitions by @maartenpaauw in https://github.com/spatie/laravel-model-states/pull/259Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.7.1...2.7.2
Use jsonSerialize in StateCaster by @piotrjoniec in https://github.com/spatie/laravel-model-states/pull/252
Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.7.0...2.7.1
Implement SerializesCastableAttributes in StateCaster by @piotrjoniec in https://github.com/spatie/laravel-model-states/pull/251
Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.6.2...2.7.0
Add support for laravel 11 by @shuvroroy in https://github.com/spatie/laravel-model-states/pull/249
Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.6.1...2.6.2
Typo in 01-configuring-states.md by @MarceauKa in https://github.com/spatie/laravel-model-states/pull/241
Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.6.0...2.6.1
Feature/Method to allow all state transitions by @fmeccanici in https://github.com/spatie/laravel-model-states/pull/238
Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.5.0...2.6.0
Bump actions/checkout from 3 to 4 by @dependabot in https://github.com/spatie/laravel-model-states/pull/236
Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.4.6...2.5.0
Don't assume scandir() always returns current and parent directory first by @sebastiandedeyne in https://github.com/spatie/laravel-model-states/pull/2
Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.4.5...2.4.6
Refactor tests to pest by @AyoobMH in https://github.com/spatie/laravel-model-states/pull/217
Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.4.4...2.4.5
Add missing RegisterState Attribute by @ralphjsmit in https://github.com/spatie/laravel-model-states/pull/224
RegisterState Attribute by @ralphjsmit in https://github.com/spatie/laravel-model-states/pull/224Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.4.3...2.4.4
Recommend not to use hypens in the name by @barclaymichael in https://github.com/spatie/laravel-model-states/pull/210
Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.4.2...2.4.3
Removed Model type enforcement and replaced with PHPDoc by @luckcolors in https://github.com/spatie/laravel-model-states/pull/208
Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.4.1...2.4.2
Update .gitattributes by @angeljqv in https://github.com/spatie/laravel-model-states/pull/205
Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.4.0...2.4.1
Manually register concrete state classes by @javoscript in https://github.com/spatie/laravel-model-states/pull/203
Full Changelog: https://github.com/spatie/laravel-model-states/compare/2.3.0...2.4.0
Nothing published for this version
Better internal use of getMorphClass
getMorphClass (#198)Nothing published for this version
Nothing published for this version
Support for custom transition classes in transitionableStates method
transitionableStates methodSupport for custom transition classes' canTransition in State::canTransitionTo
canTransition in State::canTransitionTo (#185)- Add default transition config
Add State::getModel() and State::getField()
State::getModel() and State::getField()Fix bug on two consecutive transitions
The biggest change in v2 is that states now know which fields they belong to. So instead of having to pass in fields like so:
The biggest change in v2 is that states now know which fields they belong to. So instead of having to pass in fields like so:
$model->canTransitionTo(StateB::class, 'status');
You can now do:
$model->status->canTransitionTo(StateB::class);
This change means that a lot of boilerplate code can be removed. Also keep in mind that this package wants you to always use state objects, and never their serialized values. That's why many other methods have been removed, in favour of Laravel's built-in model casts.
HasStates::transitionableStates(string $fromClass, string $field) has been removed.State::transitionableStates() now doesn't need the $field parameter anymore.HasStates::getStates() now returns the morph values instead of the hardcoded class names.State::find() has been removed.State::isOneOf() is removed, State::equals now accepts multiple state objects or morph classes.State::is() is removed, you should use State::equals().laravel/framework:^8php:^7.4finalState in StateChanged event- add support for PHP 8.0
- add support for Laravel 8
Add getters for TransitionNotFound attributes
TransitionNotFound attributes (#99)- Add canTransitionTo
canTransitionTo (#92)- Support 0 state
0 state (#89)Support model::updated state casting (#88, 351c008)
change static:: call to self:: for private State::resolveStateMapping method
static:: call to self:: for private State::resolveStateMapping method (#75)- add support for Laravel 7
Add support for fully qualified column names in whereState scope
whereState scope (#63)❗️ $finalState in the StateChanged event is deprecated and will always be null. This is because of a fix for bug #49. This fix might have unforeseen e…
$finalState in the StateChanged event is deprecated and will always be null. This is because of a fix for bug #49. This fix might have unforeseen effects if you're using StateChanged.Fix for unknown $modelClass variable
Return Eloquent model when using transitionTo method directly
Add better exceptions and Ignition support
- Revert 06a4359
Allow to get transitional states
- Add state listing methods
Proper support for non-string columns
Proper support for JSON serialise
- Default support via new
new- Improved default support
Your coding agent can read these notes before it upgrades. Set up the MCP server →