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

Finite Laravel Package

yohang/finite

yohang/finite is a lightweight PHP finite state machine library for modeling workflows and state transitions. Define states, transitions, guards, and callbacks with a fluent API, and use it in Laravel or any PHP application.

Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • yohang/finite is a framework-agnostic PHP finite state machine, not a Laravel package. It provides the graph primitive — states, transitions, events, guards and pre/post-transition hooks — and deliberately leaves persistence, transport and authorization to the application.
  • That separation is a good architectural fit for domain services, form requests, jobs and console commands, where a transition can be expressed explicitly. It is a poor fit for teams expecting state to be an attribute of an Eloquent model with automatic guards, casts and audit trails; yohang/finite will not give you those out of the box.
  • The in-memory machine definition is cheap to construct and easy to unit test, which suits a codebase where workflow rules change independently of the HTTP layer.

Integration feasibility

  • Installation is a single Composer dependency. There is no service provider, facade, config stub or published migration, so first value requires an in-house adapter: a factory or container binding to build machines from config, a persistence mapping between machine state and a database column, and a wrapper that runs transitions inside a transaction with row-level locking.
  • The library's optional Symfony EventDispatcher bridge does not map cleanly onto Laravel's dispatcher; expect a thin translation layer if transition events need to feed Laravel listeners, broadcasting or queues.
  • Overall effort is modest but non-trivial — realistically one to three engineering days for a working adapter and tests, excluding guards, authorization and audit.

Technical risk

  • Primary risk is dependency health, not code quality. The package is small, mature and MIT-licensed, with meaningful adoption (~1.3k stars), but it appears to be maintained by a very small team. The December 2025 release suggests it is still alive, but release cadence and issue responsiveness should be verified before committing.
  • Feature risk: concurrency control, audit history, visualization, transition authorization and multi-machine-per-entity support are not solved by the library. Each becomes an internal build item.
  • Displacement risk: Symfony Workflow (heavier, richer graph semantics and Laravel integrations exist) and spatie/laravel-model-states (more idiomatic Eloquent coupling) are credible alternatives. Choosing finite is choosing minimalism and owning the integration glue.

Key questions

  • Where does state live — a single status column, a history table, or both — and who is allowed to write it directly?
  • What concurrency guarantees are required (pessimistic locks, optimistic version columns, queued transitions)?
  • Is an immutable transition audit trail a compliance requirement, or nice-to-have?
  • Do downstream systems need transition events on Laravel's dispatcher, and must those be reliable across queue retries?
  • Will more than one workflow exist per entity, and does the team accept owning all the glue code indefinitely?

Integration Approach

Stack fit

  • Compatible with PHP 8.x and any Laravel version that supports it; no framework constraints to fight. Works cleanly with PHPUnit for testing transition rules in isolation, which is where most of the value is: state-machine logic becomes pure, fast unit tests rather than feature tests through HTTP.
  • Fits best as an application-layer service invoked by controllers, jobs and commands. It should not be reached for inside Eloquent observers, where implicit transitions become hard to trace.

Migration path

  • Introduce the machine alongside existing status handling rather than replacing it. Define the graph for one workflow, route new writes through the transition service, and leave legacy setters in place behind a deprecation shim.
  • For each legacy code path, wrap the direct status assignment in a transition call and assert equivalence in tests. Once write-paths are consolidated, remove direct column updates and add a database constraint or model guard that rejects unapproved state writes.
  • Sequence a second workflow only after the first has run in production for a release cycle, so the adapter is proven before it becomes a shared dependency.

Compatibility

  • No first-party Laravel support means the team owns version upgrades. Pin the dependency, run it in CI against the current PHP and Laravel matrix, and treat minor releases as review-required rather than auto-merged.
  • Watch for interaction with queued jobs and retries: a transition replayed after a retry must be idempotent or explicitly rejected.

Sequencing

  1. Spike: one workflow, in-memory machine, unit tests, no persistence.
  2. Adapter: container binding, config-driven graph definition, transition service.
  3. Persistence: state column, transaction and locking strategy, idempotency guard.
  4. Guards and authorization: policy checks wired into transition preconditions.
  5. Observability: transition events, structured logging, audit table if required.
  6. Rollout to a second workflow; then deprecate ad-hoc status writes and document the convention.

Operational Impact

Maintenance

  • Low maintenance surface: the library is small, its API is stable, and there is little to patch. The ongoing cost sits in the internal adapter, which the team must own and test.
  • Single-maintainer risk is real but mitigable — MIT license permits forking, and the code volume is small enough that an internal fork is a credible contingency. Budget for that possibility rather than assuming upstream responsiveness.

Support

  • Community support only, via GitHub issues; no vendor SLA, no commercial backing evident. Escalation is internal. Assign a named owner for the adapter and a documented upgrade procedure.
  • Because the library does not prescribe patterns, internal documentation is the de facto support material. Write it early.

Scaling

  • Machines are stateless and constructed per operation, so horizontal scaling is unproblematic; the bottleneck is the database round-trip per transition. Keep transitions short, avoid I/O inside guards, and do not nest transitions inside long-running transactions.
  • Throughput on a hot entity is bounded by lock contention. High-contention workflows (e.g. order fulfilment) need an explicit strategy: short critical sections, queued serialization, or optimistic concurrency with retry.

Failure modes

  • Invalid transition: throws by default — must be caught and mapped to a 409/422 rather than a 500.
  • Race conditions: two concurrent requests reading the same state and both transitioning. Without locking this silently corrupts state; this is the highest-severity failure mode.
  • State drift: direct database or admin-panel writes bypass the machine and desynchronize the graph from reality.
  • Guard and event-handler exceptions: a failing listener can leave state committed but side effects missing, or vice versa. Define the transaction boundary explicitly.
  • Configuration drift: graphs defined in code diverge from documented business rules; visualization or generated docs help.

Ramp-up

  • A PHP developer can learn the API in under a day; the concepts (states, transitions, guards) are standard. The real ramp-up is organizational: agreeing the graph, enforcing "no direct status writes," and understanding the locking model.
  • Plan a short internal walkthrough plus a documented example workflow in the codebase. New joiners should encounter one canonical pattern, not several ad-hoc variants.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
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