illuminate/bus
Laravel's command bus component. Dispatch jobs and commands through a central pipeline with support for synchronous handling, queue dispatching, and middleware-style pipes that wrap execution. Includes the dispatch() helper and Dispatchable trait used throughout Laravel.
Architecture fit — illuminate/bus is not a standalone library; it is a subtree split of laravel/framework, published so Composer can resolve the component individually. It is a first-party implementation of the command bus pattern, wired directly into the Laravel service container (handler resolution and method injection), the queue system (ShouldQueue), the event dispatcher (DispatchesEvents), and the pipeline abstraction used for middleware. Fit is therefore binary: excellent inside a Laravel 13.x+ application, and unacceptable anywhere else. There is no thin adapter to code against — the public surface is the concrete Illuminate\Contracts\Bus\Dispatcher plus the framework's own container bindings.
Integration feasibility — Inside Laravel, feasibility is effectively "zero install cost": BusServiceProvider is auto-discovered, dispatch() and dispatchSync() work out of the box, and testing is first-class via Bus::fake(). Outside Laravel, integration is not merely difficult, it is a fork-and-maintain proposition: illuminate/collections, illuminate/contracts, and illuminate/support must all resolve together, and their constraints track the Laravel minor. A foreign framework's container would have to be bridged into illuminate/container. Recommendation: scope non-Laravel use out and evaluate Symfony Messenger instead.
Technical risk — Four material risks:
handle() signatures. Nullable and optional parameters do not auto-resolve, surfacing as container errors that are hard to attribute in code review.^13.0 constraint means Bus cannot move independently of the framework. A Laravel major upgrade drags Bus with it, and pinning Bus separately inside a Laravel app creates transitive conflicts.Two figures on the package record should be discounted explicitly. "Dependents: 0" is a false negative — consumption is transitive through laravel/framework (~35k stars), so real-world reach is very high while the package page looks orphaned; this should not factor into a risk score. The 2026-10-27 release date should be reconciled against the actual composer.lock: the split's release feed is generated from framework tags and signals no independent roadmap or separate maintenance commitment.
Key questions
Bus contract?Stack fit — Native. No configuration, no new infrastructure, no additional deploy artifact. It reuses the queue connection, logger, event dispatcher, and container already in place. The only prerequisite is a running queue worker if async commands will be used.
Migration path — Incremental and reversible, which is the strongest argument for adoption:
ShouldQueue and observe throughput, retry behavior, and failure visibility before widening.App\Commands / handler locations, naming rules, Bus::fake() in feature tests — as team standards.Each step is independently shippable and revertible. Avoid a "big bang" bus migration.
Compatibility — Hard-coupled to Laravel 13.x. Pin Bus implicitly by pinning the framework; never add an explicit illuminate/bus constraint inside a Laravel application, as it will conflict with laravel/framework. For a reusable package that needs the abstraction, require illuminate/contracts at the lowest supported version instead.
Sequencing — Land conventions and test patterns before the first queued command. Retrofitting Bus::fake() coverage across dozens of commands after an incident is materially more expensive than establishing it at adoption.
Maintenance — Near-zero direct ownership. This is framework-maintained code tracking Laravel's release cycle; the team inherits upgrades rather than carrying patch obligations. Cost shifts from "maintain a bus" to "keep the Laravel major current." Budget for the framework upgrade window, not for Bus maintenance.
Support — Community and first-party documentation via laravel/framework; no vendor SLA and no commercial support line. Failure diagnostics are generic — a container resolution error, not "your handler is misnamed." Internal runbooks should encode the naming convention and resolution-fallback rules, otherwise every new engineer rediscovers them.
Scaling — Bus itself is stateless; scaling means horizontal queue workers plus the usual app-tier scaling. The real levers are queue partitioning (onQueue, onConnection), command chaining, and idempotency design — Bus supplies the hooks, not the guarantees. Watch for commands drifting into an RPC layer: deep chains raise latency and complicate tracing without correlation IDs injected via middleware.
Failure modes — Enumerate and monitor:
failed_jobs; requires table monitoring and alerting.Ramp-up — Low for anyone with Laravel experience: one concept (dispatch vs dispatchSync), one convention (handler naming), one testing idiom (Bus::fake()). Roughly a day for a mid-level Laravel developer to be productive, plus a short ADR and two or three worked examples to keep it consistent. The larger cost is judgment — teaching when not to reach for a command — which is a code-review concern for the first month or two, not a training item.
TPM bottom line — Adopt inside Laravel 13+ with a stated justification and the four-step sequencing above; marginal cost is close to zero and the architectural payoff is real once middleware and queueing are in play. Do not treat it as a portable library, do not let it become the default for every operation, and invest early in the naming and test conventions that turn its silent failure modes into loud ones.
How can I help you explore Laravel packages today?