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

Workflow Bundle Laravel Package

lexik/workflow-bundle

LexikWorkflowBundle integrates Symfony Workflow into Symfony applications with DI configuration, workflow visualization, and Doctrine entity state tracking.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit: none in a Laravel codebase. lexik/workflow-bundle is a Symfony bundle, not a Composer library with a framework-neutral API. Its integration surface is the Symfony full-stack kernel: a Bundle subclass, a DependencyInjection/*Extension that loads XML/YAML service definitions, compiler passes, and kernel.event_listener tags. Laravel has no bundle registry, no ContainerBuilder compiler passes, and no tagged-service discovery — only service providers and the container's bind/singleton API. Every extension point this package depends on is absent or semantically different.

The second mismatch is persistence. The bundle is Doctrine ORM-centric: workflow state is modelled through Doctrine entity mapping and Doctrine event subscribers. A Laravel integration would need to reach through the bundle's Doctrine assumptions to Eloquent models, which means replacing rather than reusing the core.

Integration feasibility: a port, not an integration. Composer will happily install the package, but resolution is where it breaks. Laravel 10/11 require symfony/* components at ^6.0/^7.0; this bundle targets Symfony 2.x (symfony/framework-bundle ~2.3, symfony/dependency-injection ~2.3), i.e. PHP 5.3–5.6 era. You cannot satisfy both constraint sets in one tree. The realistic paths are:

  • Vendor the source as a reference implementation and reimplement the workflow definition/transition semantics natively. Cost: days, not hours, but bounded.
  • Ignore the bundle and use symfony/workflow directly. The standalone component is framework-agnostic, actively maintained, PHP 8.2-compatible, and is precisely what obsoleted this bundle in the first place. A thin Laravel service provider plus an Eloquent-backed marking store gets ~90% of the value with a supported dependency.
  • Fork and rewrite. Highest cost, zero upstream, and you inherit the maintenance burden permanently.

Technical risk: high and asymmetric. The repository is archived, has 126 stars, and zero dependents — the dependent count is the decisive signal. A package with real utility in the Symfony ecosystem would have dozens to hundreds of dependents. Zero means the ecosystem has already routed around it, most likely to the native component. Archived status means no security patches, no PHP 8.x fixes, and no response to an upstream CVE in a transitive Symfony 2.x dependency. The opportunity: 6.38 score is measuring absence of competition, not presence of value — it should be read as "nobody is here because nobody needs to be."

Key questions before any decision:

  1. What workflow semantics are actually required — linear approval chains, or genuine state machines with parallel branches and sub-workflows? (symfony/workflow supports both; a hand-rolled implementation usually only needs the former.)
  2. Is the persistence requirement a single state column on an existing Eloquent model, or a full transition audit trail?
  3. Do we need guard conditions, and do they need to be evaluated against domain objects or just scalar context?
  4. Is time-boxed adoption a constraint, i.e. is there a deadline that makes "spike on symfony/workflow" too slow?
  5. Who owns the decision to take on a dependency with no upstream maintainer, and has that been accepted in writing?

Integration Approach

Stack fit: poor as-is, good after substitution. The correct target stack for a Laravel application is Laravel 10/11 on PHP 8.2+, with symfony/workflow ^7 as the engine. That component is a first-class Symfony package but carries no framework coupling — it needs a Definition, a MarkingStoreInterface, and optionally a EventDispatcherInterface. All three have clean Laravel analogues:

  • Definition: a PHP config array or a config/workflows.php file compiled at boot.
  • Marking store: a MethodMarkingStore writing to an Eloquent state attribute, or a custom store backed by a workflow_transitions table for audit.
  • Dispatcher: Laravel's dispatcher, or the Symfony one adapted via a small bridge.

Migration path. There is no meaningful data migration from this bundle because it almost certainly isn't running anywhere — zero dependents implies no production corpus to migrate. The migration is conceptual: read Lexik\Bundle\WorkflowBundle for its config schema (states, transitions, guards), confirm nothing there is semantically richer than symfony/workflow already provides (it is not — the native component superseded it), and port the definition shape.

Compatibility. Concretely: PHP 8.1+, Laravel 10/11, symfony/workflow ^6.4 || ^7.0, symfony/event-dispatcher ^6.4 || ^7.0. Any transitive pull of symfony/framework-bundle ~2.3, doctrine/orm ~2.4, or PHP <7.0 constraints should be treated as a hard stop, not something to resolve with --ignore-platform-reqs. Suppressing platform requirements here buys a runtime failure in production rather than a build failure in CI.

Sequencing.

  1. Week 1 — semantics. Enumerate the actual states/transitions from the product requirement, independent of any library. Produce a definition document. This is the artifact that survives regardless of engine choice.
  2. Week 1 — spike. Stand up symfony/workflow in a branch behind a WorkflowServiceProvider; model one real approval flow on a single Eloquent model. Success criterion: a transition fires, persists, and emits an event.
  3. Week 2 — persistence decision. Choose inline column vs audit table. If audit is required, build the marking store now; retrofitting audit later means replaying history you didn't record.
  4. Week 2 — guard and event wiring. Land guards as ->guard() closures or listener classes; wire transition events into the existing queue if side effects are slow.
  5. Week 3 — roll out one flow, then template the pattern. Do not build a generic workflow DSL for the second use case until the second use case exists.

Explicitly: do not sequence "install lexik/workflow-bundle and adapt." That ordering inverts the effort — you would spend the budget fighting Composer and Symfony 2 idioms before writing a line of domain logic.

Operational Impact

Maintenance. The package is archived, which is a terminal state. There is no upstream to merge a patch into, no release cadence, and no possibility of a security fix. If adopted, the fork becomes an internal product with a named owner and a recurring maintenance budget — an obligation usually invisible in the initial estimate. Substituting symfony/workflow transfers that obligation to a funded team with a published BC policy.

Support. Zero dependents means zero community gravity: no Stack Overflow corpus, no third-party tutorials referencing current versions, no GitHub issue history reflecting modern PHP. Engineering time gets spent on archaeology — reading 2013-era Symfony 2 bundle conventions to answer questions that the native component documents directly. Debugging an unknown future failure will be single-threaded on whichever engineer did the original port.

Scaling. The engine itself is in-process and cheap; a workflow transition is a handful of function calls over an array of places. The realistic scaling concerns are around it, not in it:

  • Persistence contention. Concurrent transitions on the same record need optimistic locking (a version column or lockForUpdate). This bundle predates the concern and provides no guidance; a native implementation must add it deliberately.
  • Side-effect fan-out. Transition events that trigger email, webhooks, or downstream writes must go through the queue. Synchronous listeners inside a transition turn a fast operation into one that fails at the speed of your slowest dependency.
  • Audit table growth. If transitions are logged, that table grows with every state change and needs retention policy and indexing on (model_type, model_id, created_at) from day one.

Failure modes.

  • Composer resolution failure — the expected first outcome of composer require; presents as an unreadable constraint-solver dump. Cost: half a day, recoverable.
  • Silent platform-requirement suppression — --ignore-platform-reqs installs, then fatals at autoload or at the first Symfony 2 container call in production. Highest-severity failure because it defers detection past CI.
  • Half-completed transition — state written but the side effect failed, or vice versa. Mitigation: wrap the transition and its synchronous side effects in one DB transaction; push non-transactional work to the queue with idempotency keys.
  • Stuck workflows — no valid transition from the current state, typically from a definition change deployed without a migration plan for in-flight records. Mitigation: version your definitions and treat in-flight records as a data migration on every change.
  • Orphaned marking store — if a custom store is added after records already exist, older rows have no marking and fail silently depending on null handling.

Ramp-up. For an engineer fluent in Laravel: native symfony/workflow is roughly a day to productive, because the concepts (places, transitions, marking store, guards) map cleanly and the docs are current. This bundle is closer to a week of negative-value ramp-up: the engineer learns Symfony 2 bundle conventions, Doctrine event systems, and a DI container they will not otherwise use in this codebase, and ends with knowledge applicable only to the fork. That asymmetry — a day of supported learning versus a week of unsupported learning for strictly less capability — is the whole assessment in one line.

Recommendation. Do not adopt. Treat the repository as a design reference for workflow modelling, and implement against symfony/workflow ^7 behind a Laravel service provider with an Eloquent marking store. Budget roughly three days of engineering for the equivalent capability, with an actively maintained dependency and no internal fork to own.

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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums