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

Cqrs Bundle Laravel Package

lmc/cqrs-bundle

A PHP CQRS bundle that separates write commands from read queries, giving you clean command and query buses with handlers, middleware support, and a structured way to organize business logic in your application.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit — the mismatch is unchanged and now version-confirmed. lmc/cqrs-bundle remains a Symfony bundle, not a Laravel package. Release 2.0.0 reinforces this: the headline changes are Symfony-version support policy (allow Symfony 6, drop 4.4/5.1) and adoption of PHP 8.1 language features in the bundle's own signatures. The value is still concentrated in Bundle registration, DI extension loading, compiler passes, and service tagging — none of which exist in Laravel's container. What is portable is lmc/cqrs (the underlying bus library): handler lookup, middleware, no event sourcing. Laravel adoption means pinning 2.0.0 of the library and discarding the bundle, replacing auto-wiring with a hand-written service provider.

Integration feasibility — moderated by 2.0.0, and the risk has moved rather than disappeared. The PHP constraint is now explicit and, on balance, helpful: requiring PHP 8.1 puts the package at the same floor as Laravel 10, and 8.2/8.3 satisfy a >=8.1 floor. The prior "likely broken on modern PHP" concern is downgraded. The Symfony ceiling is now the primary blocker: 2.0.0 declares support for Symfony 6 but stops there, while Laravel 11 and 12 pull Symfony 7 components. A symfony/*: ^7 transitive requirement in the framework is a hard Composer conflict, and it is the single cheapest thing to test. Effort to wrap the library in a bounded Laravel context remains a few days, not a few hours.

Technical risk — still high, with the shape of the risk revised.

  • Breaking changes in 2.0.0 (new language features, changed method signatures, dropped Symfony 4.4/5.1). Any tutorial, blog post, or example implementation we find online almost certainly targets 1.x and will not compile against 2.0.0. Documentation debt is now a concrete onboarding cost, not a vague one.
  • Staleness unchanged. 2.0.0 is dated 2022-05-06 — it is the terminal release, not evidence of renewed activity. Two-plus years without a follow-up, with Symfony 7 shipping in that window, tells us the maintenance posture is dormant. Do not read a major version bump as a revival signal.
  • Adoption signals remain effectively nil: 1 star, 0 dependents. No downstream usage means no community-discovered edge cases and no third-party fixes for the 2.0 signature changes.
  • Bus factor: single-vendor (LMC), low external traction. A BC-breaking 2.0 followed by silence is the classic abandonment pattern.
  • No async story: commands and queries stay synchronous in-process; queues, retries, and transport are ours to build, and 2.0.0 does nothing here.
  • Silent failure surface: handler-not-found behaviour, middleware ordering, and transaction boundaries remain unenforced conventions.

Key questions for the team.

  1. Does our target Laravel version resolve against symfony/*: ^7? If yes, this evaluation ends at the Composer dry-run and the answer is "in-house bus."
  2. Do we need CQRS proper (separate read/write models, projections), or a command bus plus action classes? Most Laravel codebases want the latter, and Laravel already supplies the primitives.
  3. Given 2.0.0 is the last release, are we comfortable pinning a dependency whose upstream went quiet immediately after a BC break — and does that make the fork decision default rather than contingent?
  4. Why this over Symfony Messenger (maintained, framework-agnostic, bridgeable into Laravel) or a small in-house bus? And is the driving need architectural discipline, or porting convention from an existing LMC-built Symfony app that is already on 2.x?

Integration Approach

Stack fit. Poor as packaged; workable only as a library-only dependency pinned to ^2.0. Treat lmc/cqrs as a candidate implementation of a bus abstraction we own. Define CommandBus/QueryBus interfaces in the domain layer and bind the vendor implementation behind them — this keeps exit cheap and is the most important structural decision here, more so now that the upstream looks terminal.

Migration path. Per-module refactoring, never big-bang, and orthogonal to framework migration.

  1. Constraint check first (same afternoon): composer require lmc/cqrs:^2.0 --dry-run --with-all-dependencies against the real application. Confirm no symfony/*: ^7 collision and no PHP upper-bound surprise. If it fails, stop and close the evaluation — this is the expected outcome on Laravel 11+.
  2. Spike (1 sprint, one bounded context): install lmc/cqrs:^2.0 alone in a branch, register one query handler via a service provider. Target 2.0 signatures explicitly — do not lift handler examples from 1.x material; the method signatures changed.
  3. Queries first. Read-side handlers are low-risk, carry no transaction semantics, and demonstrate value quickly (reporting/dashboard aggregation).
  4. Commands second, one write path at a time, with explicit DB::transaction wrapping at the dispatch boundary — the library will not do this for you.
  5. Never event sourcing on this package. No event store exists; retrofitting one is a separate project.

Compatibility. Pin 2.0.0 exactly and commit the lockfile diff in the ADR. Validate transitive Symfony constraints against what laravel/framework already requires (HttpFoundation, Console, Finder, Translation, Process) — on Laravel 10 this likely resolves; on Laravel 11/12 it likely does not. Also verify the PHP floor assumption: 2.0.0 requires 8.1, which is satisfied by 8.2/8.3, but no upper bound has been tested upstream and no one has run it there.

Sequencing. Do not start until the abstraction interfaces exist and at least one alternative (Messenger or in-house) is priced. Run the constraint check and the spike in parallel with a written ADR; the decision record is the deliverable, not the working demo. Treat 2.0.0 as a frozen snapshot — no upstream fixes should be assumed.

Operational Impact

Maintenance. Assume we maintain it. Budget roughly a day per major PHP or Laravel upgrade to verify or patch, plus the initial fork setup if we vendor it (vcs repository or a composer-patches entry). The 2.0.0 release shows the maintainer's pattern: BC-breaking signature changes on major bumps, then silence. That means our fork is not a one-time copy — it is a commitment to re-do those signature migrations ourselves the next time PHP or Symfony moves. Contrast with Symfony Messenger, where that cost sits with a well-resourced upstream.

Support. No SLA, no commercial backing evident, no dependents to lean on. Escalation path is "open an issue and wait, or fix it ourselves" — and after two years of silence on a 2.0.0, the realistic expectation is the latter. For a system on a revenue path, that risk must be accepted explicitly by the tech lead, not absorbed silently by the implementer.

Scaling. In-process and synchronous by design — fine for request-scoped work, wrong for anything long-running. As load grows the remedy is offloading commands to Laravel queues, which requires writing the async dispatch layer ourselves: effectively reimplementing a slice of Messenger. Plan for that cost to appear later rather than believing the package covers it; 2.0.0 adds nothing here.

Failure modes to instrument from day one.

  • Handler not found → runtime exception at dispatch; surface the command class name in logs, not a generic 500.
  • Middleware/transaction ordering mistakes → partial writes; enforce transaction wrapping in a single base dispatcher, never per-handler.
  • Silent no-op handlers → dispatch returns without effect; structured logging with correlation IDs on every command dispatch.
  • Dependency rot on upgrade → the 2.0.0 BC break is the template; a future Symfony 7/8 or PHP 8.5 bump will strand us. Mitigated only by the abstraction layer described above.
  • Signature drift from 1.x examples → 2.0's changed method signatures mean copied snippets fail confusingly; pin the version in the ADR and in onboarding docs.

Ramp-up. Low conceptual cost (CQRS-without-event-sourcing is a small idea) but non-zero and now slightly higher convention cost: engineers must learn the library's handler resolution and middleware semantics, which are undocumented outside the repo, and must disregard the larger body of 1.x material that no longer matches. Estimate half a day per engineer plus the spike's findings, and capture them in the ADR so the second team does not repeat the work.

Bottom line. 2.0.0 clarifies the picture without improving it: PHP 8.1 is a non-issue, but Symfony 6 as the ceiling collides with modern Laravel, and a BC-breaking major followed by two years of silence is abandonment evidence rather than maintenance evidence. The defensible play is unchanged but firmer — own the abstraction, treat the package as a reference implementation, and run the Composer dry-run before any spike. If it collides on Symfony 7, or if the spike cannot move off 1.x examples within an afternoon, implement the bus in-house and close the evaluation.

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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin