Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

State Machine Laravel Package

caner/state-machine

A lightweight Laravel state machine for Eloquent models. Define states, transitions and guards, apply them safely with validation, events and history, and keep workflow logic out of controllers and models. Ideal for approvals, orders and multi-step processes.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Feature scoping: Any feature where a record moves through a defined lifecycle — order fulfillment, payment capture/refund, subscription lifecycle, KYC/onboarding, ticket or approval workflows — needs enforced transitions. This package lets you declare those transitions once, bind them to an Eloquent model, and reject illegal moves, instead of scattering if ($order->status === 'paid') checks across controllers, jobs, and listeners.
  • Build vs. buy: The core value is small and well understood (~a few hundred lines of guard/transition logic). The buy case here is speed and consistency, not capability. A PM should treat this as a candidate for a time-boxed spike, not a platform commitment, until it's compared against a maintained alternative or an in-house enum + guard implementation.
  • Correctness as a product requirement: The "transaction-safe" framing matters for decisions where a state change and its side effect (inventory decrement, ledger entry, notification dispatch) must succeed or fail together. If your roadmap includes any money-moving or inventory-moving workflow, atomic transitions are a product-risk decision, not just an implementation detail.
  • Roadmap leverage: Introducing a formal state machine early makes later roadmap items cheaper — status-funnel analytics, audit trails of who moved what and when, permissioning by state ("only finance can move to refunded"), and customer-facing status timelines all key off a canonical state graph.
  • Use cases to prioritize: order/fulfillment pipelines, dunning and subscription states, multi-step internal approvals, document or request lifecycles. Deprioritize it for simple binary flags (active/inactive) where a state machine is overhead.
  • Adoption signal to weigh: Roughly 51 stars, no dependent packages, a single maintainer, and a release cadence that only recently resumed (1.1.0 adds Laravel 9 support, roughly a year-plus after the previous release). That's not disqualifying for a small utility, but it means the decision should be "we can own this code if needed," not "we are betting on this vendor."
  • What 1.1.0 changes: The release removes the biggest concrete blocker (Laravel 9 compatibility), adds automatic state persistence on successful transition (less glue code and fewer "forgot to save()" bugs at call sites), and improves docs with a worked example project. Together these lower the cost of a spike and raise the odds the package behaves as advertised — but they are evaluation enablers, not a maturity signal.

When to Consider This Package

Consider it when:

  • You have Eloquent models with non-trivial lifecycles (≥3 meaningful states and guarded transitions) and want the transition rules to live in one declarative place.
  • Atomicity is a real requirement — the transition and its database side effects must commit or roll back together, and you don't want to hand-roll DB::transaction() wrappers around every call site.
  • You want automatic state persistence without per-call-site save() bookkeeping — 1.1.0 handles the state write on a successful transition, which removes a common class of "state changed in memory but not in the database" defects.
  • You want a small, MIT-licensed, low-ceremony dependency you could realistically vendor or fork without inheriting a large surface area.
  • Your team is Laravel-native, comfortable reading package internals, and can absorb the evaluation cost of a low-traffic library — now lower, given the example project and refreshed docs.

Look elsewhere (or build in-house) when:

  • You need actively maintained dependencies with predictable upgrade paths. 1.1.0 confirms Laravel 9 works, but you must still verify whatever Laravel and PHP versions are actually in your stack — do not assume coverage beyond the version the maintainer explicitly tested.
  • You need supported guarantees — SLAs, security response, or long-term maintenance for a revenue-critical flow.
  • You want an ecosystem-proven choice. Compare directly against spatie/laravel-model-states, which is the de facto Laravel answer and has materially broader adoption; the PM question is whether this package's transaction-safety angle justifies the adoption risk gap.
  • You need tooling beyond the library — state graph visualization, admin UI for transitions, or event sourcing. This is a lean library, not a workflow platform.
  • Your states are trivial (two or three, no guards, no side effects). An enum plus a transitionTo() method is cheaper to own.

How to Pitch It (Stakeholders)

For executives (one paragraph): We're evaluating a small open-source Laravel component that formalizes how records move between states — order placed → paid → shipped → refunded, for example — and guarantees each move is atomic with the database writes around it. It costs nothing in license (MIT) and could reduce defect classes where records end up in impossible states, which directly affects revenue reporting and customer trust. The latest release, 1.1.0, addresses the two things that made it hard to even trial: it now supports Laravel 9, saves the new state automatically so engineers can't half-apply a transition, and ships documentation with a working example. The maturity caveat stands — small user base, single maintainer, and a slow release rhythm. Recommendation is unchanged but better informed: run a short engineering spike on one non-critical workflow, then decide adopt / vendor-and-own / decline. Worst case we vendor a few hundred lines of code and own it; best case it saves us building transition logic from scratch.

For engineering (the ask): Re-run the spike with 1.1.0 and validate the new behavior specifically: confirm compatibility with our exact Laravel and PHP versions (only Laravel 9 is claimed), and verify how "automatic state update" persists — does it fire inside the same transaction as our side effects, does it respect saveQuietly/events, does it behave under nested transactions and queued jobs, and does it interact correctly with model observers and audit hooks. Still evaluate against spatie/laravel-model-states and an in-house enum-plus-guards approach. Also confirm guard/authorization extensibility and test coverage. Report back with adopt / vendor-and-own / decline, with the transition rules owned in configuration rather than controller code either way.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core