sylius/flow-bundle
Sylius FlowBundle provides a flexible workflow and state-machine layer for Symfony applications, letting developers define flows, steps, transitions, and callbacks to model checkout, order, or custom business processes with clean, configurable PHP code.
Architecture fit: mismatch at the platform boundary, fit at the domain layer. sylius/flow-bundle is a Symfony bundle, not a Laravel package — it assumes Symfony's DependencyInjection container, EventDispatcher, HttpKernel routing, and typically Doctrine. Laravel has no bundle or CompilerPass concept, so "integrating" it for a Laravel app means running two container and event systems side by side and writing adapters at each step processor. The piece worth leveraging as a TPM is the domain model, not the runtime: ordered steps (ProcessBuilder::add), a ProcessContext that carries flow storage and the request, displayAction()/forwardAction() as the GET/POST contract per step, complete() to advance, and storage-backed partial state between steps. That model is small, readable, and directly translatable to Laravel primitives.
Integration feasibility: low as a dependency, high as a specification. Composer-installing it is mechanically possible but places Symfony components alongside Illuminate with no shared config, container, or routing surface. The realistic TPM-approved path is to treat the repository as a design reference: read Process/Builder/ProcessBuilder.php (the step DSL), Process/Step/ControllerStep.php (the step contract), and the storage abstraction, then reimplement the pattern in our idiom. That is a 1–2 sprint effort for a hardened, tested version with guard middleware and a persisted state store — not an integration.
Technical risk: high, and concentrated in maintenance status rather than quality. The repository is archived/read-only with zero dependents and 83 stars. That means no upstream fixes, no security response channel, no demonstrated third-party production usage, and no evidence of PHP 8.2/8.3 or modern Symfony compatibility. An archived package that breaks on a PHP minor upgrade has no remediation path other than our own fork. The 0.8075 score and 7.31 opportunity metric reward the underlying pattern; they should not be read as package viability.
Key questions before any commitment:
Stack fit: adopt the pattern, not the package. The clean port maps the bundle's concepts onto Laravel primitives: a Step interface with display()/process() methods; a Flow definition object holding ordered steps and transition rules; a FlowManager resolving the active step from route and session; a FlowState store backed by session or cache; and middleware acting as a step guard to reject out-of-order access. Route registration can be generated from the flow definition rather than hand-declared per step, which is the single biggest reduction in boilerplate the source offers.
Migration path: greenfield, not incremental. There is nothing to migrate from on Laravel. Two viable tracks for the TPM to weigh: (a) build the Laravel-native flow layer described above, using this repository as the specification for step semantics, result handling, and storage; or (b) evaluate symfony/workflow as a framework-agnostic state machine — actively maintained, genuine port story, but it models state transitions rather than wizard UI steps and still needs a presentation layer. For simple linear wizards, a purpose-built implementation is likely smaller than either dependency. Recommend the TPM record this as an explicit build-vs-adopt decision with the spike output attached.
Compatibility. Do not assume PHP 8.x or current-Laravel compatibility. Any decision to vendor the source should be preceded by a spike that runs the step orchestration logic in isolation under our target runtime. The bundle conventions — configuration tree, CompilerPass, service tagging — will not port and should be discarded rather than emulated.
Sequencing:
symfony/workflow vs. internal implementation) using the spike output; publish the decision record.Maintenance. Archived status transfers full ownership to us regardless of track. If we vendor or fork, we inherit the code plus an implicit permanent maintenance obligation with no upstream to rebase against. If we port, we own less code and it fits our conventions, test suite, and observability. The port is the lower total-cost option; the dependency is the higher one, and it is deferred rather than avoided.
Support. There is no maintainer, no issue triage, and — with 83 stars and zero dependents — effectively no community corpus to draw on for troubleshooting. Internal team knowledge becomes the only support channel, which argues for keeping the implementation small, documented, and in our own idioms rather than adopting unfamiliar Symfony bundle conventions that only one or two engineers can read.
Scaling. Session-backed flow state is the default assumption for this class of bundle and becomes a constraint under horizontal scaling: sticky sessions or a shared session store (Redis) are required, and multi-device resume is not achievable without moving state to a persisted store keyed to the user or cart. Plan the state-store abstraction early so session-to-database is a swap, not a rewrite. Route the TPM's capacity conversation accordingly: this is a small feature with a non-trivial operational tail.
Failure modes to design against:
Ramp-up. Budget one day of source reading plus a short spike for a mid-level engineer to be productive against the pattern; a full port is a 1–2 sprint effort once the contract is agreed. Recommend the TPM position it to stakeholders as free design reference, zero supply-chain cost, do not add to the dependency graph, and use it to sharpen checkout or onboarding estimates rather than to shorten them by borrowing code.
How can I help you explore Laravel packages today?