enqueue/messenger-adapter
Symfony Messenger transport built on Enqueue, letting you send and receive messages through any supported broker such as AMQP or Redis. Configure the Enqueue bundle, point Messenger at enqueue://default, route your messages, and consume—with per-queue, exchange, delay, TTL, and priority options.
Architecture fit — conditional, and the condition is unusual. This package is a transport shim between symfony/messenger's TransportInterface and Enqueue's broker abstraction. Laravel does not use Symfony Messenger; its messaging backbone is Illuminate\Contracts\Bus\Dispatcher plus Illuminate\Queue drivers. So the adapter solves a problem a Laravel application does not natively have. It is only architecturally coherent in two scenarios: (a) the team has deliberately adopted Messenger's bus/middleware/envelope model inside a Laravel app, typically because message contracts and consumers are shared with Symfony services elsewhere in the estate; or (b) you require a broker that Symfony does not support natively (Kafka, STOMP, Gearman) and want Messenger semantics on top. For a standard Laravel workload it introduces a second, parallel messaging stack — two worker runtimes, two retry/DLQ models, two serialization contracts — which is a governance and observability tax with no offsetting benefit.
Integration feasibility — install is trivial, wiring is not. composer require is one line, but the README's path assumes Symfony Flex recipes and enqueue/enqueue-bundle: YAML under config/packages/, environment-variable-driven DSN resolution, and a Symfony DI container. None of that exists in Laravel. You will hand-write a service provider that constructs the Enqueue transport, a config loader to replace the YAML, and a consumer entrypoint — messenger:consume is a Symfony Console command expecting a Messenger service locator, routable bus, and event dispatcher, so registering it with Artisan is real glue code, not configuration. Note also the documentation/identity mismatch: the install line references the legacy sroze/messenger-enqueue-transport while the repository is enqueue/messenger-adapter. Resolve the canonical package name and version on Packagist before it lands in a lockfile.
Technical risk — moderate-to-high, concentrated in maintenance rather than runtime. Signals are thin: ~201 stars, zero dependents, a composite score near 24/100 and an opportunity score near 22. The code is a thin adapter, so the blast radius of a defect is small, but there is no community buffer if it breaks. The breakage vector is upstream drift in Messenger's TransportInterface (DSN parsing, setup(), keepalive, message-count semantics) and in Enqueue's own transport/context API. Enqueue also carries a heavy dependency graph and a bundle-oriented configuration model that assumes Symfony DI. Strategically, Symfony has been absorbing native transports (AMQP, Redis, Doctrine, Beanstalkd, SQS, Pub/Sub), which narrows Enqueue's differentiator to edge brokers and existing Enqueue investments. Treat the 2026-02-08 release date with caution: verify whether it reflects active feature work or a split-repository tag before reading it as vitality. There is no evidenced security policy. MIT licensing does mean fork-and-patch is a legitimate contingency.
Key questions to resolve before any commitment:
Illuminate\Queue does not?Stack fit. Choose the path by requirement, not by package availability:
| Requirement | Recommended path |
|---|---|
| Standard async jobs in Laravel | Laravel queue drivers (Redis, SQS, database, community AMQP) |
| Kafka/STOMP broker from Laravel | Enqueue integrated directly, not via this adapter |
| Shared Messenger envelopes with Symfony services | This adapter, confined to a single bridging service |
| Symfony Messenger's middleware model as a hard requirement | This adapter, with a fork contingency budgeted |
The workable pattern, if it proceeds at all, is a messaging sidecar: a discrete Laravel module or service whose only responsibility is bridging, with its own queue names, its own worker supervisor entrypoint, and its own service provider. Everything outside that boundary keeps using Illuminate\Queue. That containment is what makes removal a configuration change rather than a refactor.
Migration path.
symfony/messenger + enqueue/enqueue + this adapter, hand-wired transport and a consume command; move one message end-to-end to the target broker.Illuminate\Queue.Compatibility. Pin Messenger and Enqueue to explicit minor versions and record them in an ADR. Verify the Composer solver against Laravel's transitive symfony/* constraints (Laravel ships Console, HttpFoundation, Process, etc.) before committing — this is the most likely place the spike fails. Confirm PHP version support, required extensions (ext-amqp, ext-redis), and broker-version specifics: quorum queues, TLS, auth, and prefetch semantics. Confirm the canonical package name and current version from Packagist rather than the README.
Sequencing. Week 0: ADR and spike go/no-go criteria. Week 1: spike plus contract test. Week 2: module wiring, observability, supervisor configuration, failure-transport replay procedure. Week 3+: shadow, then one bounded context. Do not sequence a broad rollout; if the spike fails on Composer conflicts or contract mismatch, stop there and default to Laravel's queue system.
Maintenance. Expect to be the de facto maintainer of the glue layer. The package is thin and low-traffic, so upstream fixes may lag; budget for a fork-and-patch capability rather than assuming responsiveness. You will be tracking two dependency trees (Messenger and Enqueue) for advisories and breaking changes, and you should re-run the contract test on every Messenger minor bump. Assign a named owner; unowned glue is how dual-stack systems rot.
Support and ramp-up. Community support is thin given stars, dependents, and composite score — there is no vendor SLA and little Stack Overflow surface. Engineers must learn three overlapping abstractions simultaneously: Messenger (envelope, stamps, middleware, retry strategy, transports vs. failure transports), Enqueue (context, transport factory, DSN options, bundle-style configuration), and Laravel's queue mental model they already know. Realistic ramp-up is one to two weeks per engineer to be productive, longer to be safe on call. Write the runbook during the spike, not after.
Scaling. Scaling is per-consumer messenger:consume processes under supervisor or systemd, entirely separate from Horizon. You lose Horizon's dashboards, autoscaling, throughput metrics, and job introspection unless you rebuild equivalents against broker metrics. Concurrency and prefetch are tuned through Enqueue transport options and worker flags and must be validated against broker limits. The adapter itself is not a throughput bottleneck — a small DSN and serialization layer — so the ceiling remains the broker plus PHP worker count, same as native.
Failure modes to design against.
failed_jobs table. Without a configured failure transport and a replay workflow, poison messages either vanish or loop indefinitely. This is the single highest-severity operational gap.setup() auto-creates exchanges and queues, a misconfigured DSN can create production topology invisibly. Gate that behaviour.TransportInterface fails at worker boot. Pin, smoke test in staging, and keep the kill switch warm.Recommendation. For a standard Laravel product, this is a no-go: use Laravel's queue drivers, or integrate Enqueue directly if a non-native broker is required. The adapter becomes defensible only when a shared-Symfony message contract or a Messenger-specific middleware requirement is confirmed — and then only as a time-boxed spike with a named owner, a contained module boundary, a contract test, and a pre-agreed removal path.
How can I help you explore Laravel packages today?