jeckel-lab/command-dispatcher-bundle
A Symfony bundle providing a lightweight command dispatcher for decoupling actions from their handlers. Dispatch command objects through a configurable bus, add middleware for cross-cutting concerns, and keep controllers thin with clean, testable service wiring.
Architecture fit — Poor (blocking mismatch). This is a Symfony Bundle, not a Laravel package. Its integration surface is Symfony-specific: a Bundle subclass, a DependencyInjection\Extension with a Configuration tree, compiler passes, and service tagging via autoconfigure. Laravel's extension surface is entirely different — service providers, config/*.php merges, container bind/singleton, and Illuminate\Contracts\Bus. There is no supported path to loading a Symfony bundle in a Laravel application, and no Laravel service provider is shipped. The underlying domain concept (a command dispatcher / command bus) is framework-agnostic in principle, but the value delivered here is the wiring, and the wiring is 100% Symfony. Assessed as a drop-in dependency, architecture fit is effectively zero.
Integration feasibility — Low without porting work. Three realistic options, in ascending cost:
dispatch(), Bus::map(), Dispatchable, queued command handlers, middleware pipelines, and ShouldQueue for async. A Laravel-native implementation of the same pattern is a 1–3 day spike and carries zero third-party risk. Adjacent mature options (league/tactician with a Laravel bridge, laravel-command-bus style packages) exist if middleware/transaction semantics are required.Technical risk — High. Concrete signals: 1 GitHub star, 0 dependents, last release 2021-12-03 (3+ years stale), single-author project. That combination means no security patching, no PHP 8.2/8.3/8.4 compatibility work, and no Symfony 6/7 support — so even in a Symfony shop the version-constraint collision would be the first blocker. Bus factor is 1. If ported into Laravel, you inherit an unpinned symfony/dependency-injection + symfony/http-kernel dependency graph that will version-skew against the Symfony components Laravel does consume (console, http-foundation, routing, translation, error-handler, var-dumper, process, mime, uid). That is a recurring Composer resolution tax for zero functional gain. Supply-chain risk is low (MIT, small surface), but abandonment risk is near-certain.
Key questions to resolve before any code is written:
Verdict: Do not adopt as a dependency. The package is architecturally incompatible with the stated stack and operationally orphaned; its only residual value is as a reference implementation for a pattern Laravel already supports natively.
Stack fit — None as-is; deliberate port or full replacement. Scoring the package at 0.665 with an opportunity score of 1.53 reflects a niche, low-signal artefact: interesting pattern, negligible ecosystem validation. Treat it as design input, not as a build dependency.
Recommended path (in order):
Illuminate\Contracts\Bus\Dispatcher, Bus::map, Pipeline, and ShouldQueue.CommandBusServiceProvider binding Dispatcher to an interface, with handler discovery via a naming convention or PHP attribute, plus a middleware pipeline for transactions and logging. This is well-trodden territory and gives full ownership.app/ or an internal company/command-bus package with MIT attribution, then rewrite the Symfony container wiring as a Laravel provider. Budget 5–8 engineer-days including tests and CI.Migration path and compatibility. Do not attempt to install the bundle into a Laravel application — there is no bridge, and pulling symfony/http-kernel into an illuminate/* dependency tree to satisfy a bundle loader is a non-starter. The realistic migration is semantic, not mechanical: any code written against the bundle's dispatcher interface should be written against a first-party CommandBus contract instead, so that a future implementation swap is a container rebind rather than a refactor. If a Symfony service already exists in the estate and uses this bundle, pin it there behind an HTTP/queue boundary and keep Laravel unaware of it.
Sequencing. (1) Confirm no Symfony footprint → closes the option entirely. (2) Capability audit against Laravel's bus. (3) Spike. (4) Decision gate: adopt native, build first-party, or defer. (5) Only if building, stand up CI with a PHP 8.1–8.4 × Laravel 10/11/12 matrix from day one. (6) Instrument before rollout — dispatch counts, handler latency, failure rates — so the pattern earns its complexity.
Explicit non-goal: adding a second, parallel dispatch mechanism alongside Laravel's. Two buses in one application is a durable source of "why didn't my handler run" incidents and should be rejected at design review.
Maintenance. As a dependency: unbounded and unrewarded — no upstream releases since December 2021, so every PHP minor bump becomes our problem to triage with no maintainer to escalate to. As a port: 5–8 days of build plus an ongoing ~1 day/quarter of dependency and compatibility upkeep, owned by a named engineer. As a replacement with Laravel's native bus: near-zero marginal maintenance, since it ships with the framework and is covered by Laravel's own security and upgrade cadence. The maintenance delta between these options is the single strongest argument in this assessment.
Support. No vendor, no SLA, no issue-triage history to model response times against, and a 1-star/0-dependent footprint means no community to lean on when something breaks. Internal escalation path would be "the one engineer who read the source." For anything on a revenue path, that is not an acceptable support posture. If a fork is unavoidable, require a documented owner, an on-call entry, and a stated deprecation trigger.
Scaling. The pattern itself is in-process and horizontally neutral — it scales exactly as the host application does, so no additional scaling concern. The real scaling risk is organisational: a bespoke dispatch layer that only two engineers understand becomes a bottleneck as the team grows, and new hires arriving from a Laravel background will expect dispatch() and the queue system, not a Symfony-derived bundle.
Failure modes to design against (regardless of implementation choice):
failed_jobs for free; a hand-rolled dispatcher does not, and this bundle predates nothing that supplies it.composer update, blocking unrelated work.Ramp-up. Symfony bundle conventions (extensions, compiler passes, tag-based autoconfiguration) are unfamiliar to a Laravel team; expect 1–2 days of onboarding per engineer just to read the package, on top of the 5–8 days to port it. By contrast, Laravel's bus is covered by documentation the team already reads. Net: the "cheap off-the-shelf option" is the expensive one here.
Bottom line for planning: recommend closing this as evaluated, not adopted, with the rationale recorded (framework mismatch, abandoned upstream, native alternative exists). Re-open only if a Symfony service enters the estate, in which case the correct move is still to pin the bundle inside that service rather than bridge it into Laravel.
How can I help you explore Laravel packages today?