revision-ten/cqrs
A lightweight CQRS package for Laravel that separates writes from reads using commands, queries, handlers, and buses. It helps organize business logic into clear, testable actions with simple Laravel-friendly integration.
Signal read. The package metadata is the headline: 2 stars, 0 dependents, MIT license, a one-line description. That is not a quality judgment — it is an absence of evidence. There is no downstream bug surface, no StackOverflow corpus, no third-party blog posts, no security review, and effectively no community triage. A composite score of 0.01 is driven almost entirely by adoption signals, not by code correctness. Treat this as an unvetted internal reference implementation until a spike proves otherwise.
Architecture fit. CQRS is a high-leverage but high-commitment architectural bet, and it only pays off where it is genuinely warranted:
It is a poor fit for CRUD-shaped domains, small teams without DDD familiarity, and greenfield products still searching for product-market fit — event-sourced schemas are expensive to reshape once product assumptions change. Evaluate the architecture decision separately from the package decision; the package is a marginal line item, the architecture is a multi-quarter commitment.
Integration feasibility. Likely a Laravel service-provider package exposing command/query buses with handler resolution via the container. The feasibility question reduces to a short list that a 1–2 week spike must close:
Technical risk. Dominated by abandonment, not by defects. Single-maintainer stewardship with no visible release cadence means a framework upgrade can strand you. Three mitigations, in order of preference:
Key questions for the maintainer team. Is the event type identified by PHP class name (rename = silent deserialization break)? Is there an upgrade/versioning story for event schemas? Octane and queue-worker compatibility? Multi-tenancy story for the event store? Is the bus middleware extensible enough for cross-cutting concerns (authz, tracing, idempotency keys)?
Stack fit. Presumably Laravel-native, which is the right shape: existing container, queue, and event primitives do most of the plumbing. Confirm whether it is Laravel-coupled or framework-agnostic — coupling is fine here and usually reduces integration surface, but it raises the cost of a future framework move.
Migration path — strangler, not big-bang. Do not retrofit event sourcing onto legacy tables. Adopt per-bounded-context:
Touching multiple contexts in one release is the classic failure mode; the blast radius is event-schema-level, not table-level.
Compatibility. Pin PHP and Laravel constraints explicitly and run the matrix in CI from day one. Verify database support against your actual production engine (JSON column handling and locking semantics differ meaningfully across MySQL/Postgres). Check for deprecated framework contracts, which are the usual cause of a hard stop at the next LTS bump.
Sequencing.
| Phase | Duration | Exit criteria |
|---|---|---|
| Spike | 1–2 wks | Event store decision, serialization/versioning proven, one aggregate round-trips |
| Adopt/fork decision | 1 wk | Go/no-go on dependency vs. vendored fork |
| Pilot context | 1 sprint | Production write path, handler tests, observability wired |
| Projections | 1–2 sprints | Rebuild + checkpoint drill succeeds under load |
| Expansion | Ongoing | Documented pattern, second context onboarded |
Front-load the spike. The dominant cost of reversing an event-sourcing decision is data migration, so the decision point must be cheap and early.
Maintenance. Assume you are the maintainer. Budget roughly 10–20% of one engineer for stewardship — tracking framework releases, patching the fork, and reviewing upgrades — plus a named owner. The license makes forking legal and inexpensive; the discipline to actually fork before you need to is what teams skip.
Support. None external. Internal documentation and a short architectural decision record are not optional; they are the difference between an asset and an orphan. Plan for onboarding material written by the pilot team while the context is fresh.
Scaling. Read scaling is CQRS's easy win. The costs sit elsewhere: unbounded event-store growth, projection rebuild wall-clock time, and snapshot policy. Size these before launch — a rebuild that takes 40 minutes is a deploy blocker; one that takes 8 hours is an incident response problem. Async projections shift pressure onto queue throughput and consumer lag, which needs its own dashboards and alerts.
Failure modes to instrument explicitly.
Ramp-up. Steep and non-linear. A mid-level Laravel team should be allowed 4–8 weeks before expected productivity, with architectural review gates during the pilot. The package itself is a day's learning; aggregates, eventual consistency, and projection design are the actual curriculum. Underinvesting here produces event-sourced code that is CRUD-with-extra-steps — the worst of both models.
Recommendation. Adopt the pattern with high confidence in the right bounded context; treat the package as a reference implementation to be spiked, then either vendored as an org-owned fork or replaced by ~2–3 engineer-weeks of in-house bus and event-store code. The 2-star count is not disqualifying — CQRS abstractions are thin and replaceable — but it does mean the package contributes no de-risking of its own, so every guarantee must be established internally before the first production event is written.
How can I help you explore Laravel packages today?