garlic/bus
garlic/bus is a Laravel package that adds a bus abstraction for dispatching commands or messages to their handlers, helping keep controllers thin and application logic organized. It is a small, early-stage package best suited to simple projects or experimentation.
garlic/bus is a Symfony 4 bundle, not a Laravel package — there is no auto-discovered service provider, no config/bus.php, and no facade. As a Laravel developer your first move is to decide whether you're integrating it or mining it for patterns, because its Symfony 4.4-era constraints will not co-install cleanly with Laravel 9+. Laravel's own symfony/messenger / symfony/console / symfony/http-foundation constraints (Symfony 6/7 in recent versions) collide with a bundle written against Symfony 4.4.
The new 1.6.17 release is a single-line bugfix — "Fix event processor" — so nothing in the above changes. It is a patch on the event-bus path, not new Laravel integration, not a new feature, not a dependency bump. Do not re-run your evaluation expecting different composer results.
Minimal steps if you want to see it actually run:
composer require garlic/bus — expect a dependency conflict. The realistic sandbox is a fresh Symfony 4.4 skeleton, not a Laravel app.src/GarlicBusBundle.php, then everything under DependencyInjection/ and Resources/config/. That is where the message bus aliases, service IDs, and middleware chain are declared. Everything else is a thin layer over Symfony Messenger.DependencyInjection/ and the event-dispatcher subscriber — that is the only thing the patch touches.final class RegisterUser { public function __construct(public string $email) {} }
class RegisterUserHandler
{
public function __invoke(RegisterUser $m) { /* ... */ }
}
$bus->dispatch(new RegisterUser('[email protected]'));
If you're staying in Laravel, skip steps 1–4 and read the source as a reference implementation of a middleware-pipelined bus. Your entry point is Illuminate\Bus\Dispatcher and Bus::pipeThrough().
Garlic Bus follows the CQRS-lite convention common to Symfony bundles of that era: separate command, query, and event buses, each assembled from a shared middleware stack. In a Symfony context that means three bus aliases injected into services, one handler per message, and transport routing in config/packages/messenger.yaml.
EventServiceProvider::$listen array.Bus::pipeThrough([...]) or job middleware (middleware() on the job class), which is the same shape.Job on a named connection, or dispatch(new X)->onQueue('events').EventDispatcher). It is a correctness fix for an existing flow, so the pattern is unchanged: events are dispatched as messages whose handlers are ordinary subscribers.Integration tips for a Laravel app:
pipeThrough list so you get the same transactional/logging envelope.ShouldQueue jobs for commands, synchronous handlers for queries, ShouldBroadcast/events for events — rather than building three literal bus instances.messenger envelopes with stamps, and make your Laravel producer/consumer honor that format. You do not need the bundle on the Laravel side to speak it.Bus::fake() mirrors mocking MessageBusInterface — assert against the message object, not the bus.Bus::pipeThrough([
WrapInTransaction::class,
LogDispatch::class,
])->dispatch(new RegisterUser('[email protected]'));
symfony/* requirements fight Laravel's own. Even an --ignore-platform-reqs install leaves you with two container abstractions and no clear owner of the boot process — don't.Kernel + ContainerBuilder. This is where most people bounce.^1.6.messenger:consume -vv. In Laravel the equivalents are php artisan queue:work -vv, queue:failed, Telescope's Jobs/Events panels, and a logging middleware at the front of pipeThrough.Stamp-style marker interface for "dispatch after commit" (mirror with DB::afterCommit), and a message-class → transport routing table in config.symfony/messenger standalone — it's the maintained upstream this bundle wraps — not this bundle.Bus + Queue + Event primitives, which are maintained and already fit your container.How can I help you explore Laravel packages today?