cqrs
Skill4 starsChanged 4 months agoMITView on GitHub
Split the write side (commands that change state and return nothing) from the read side (queries that return data and change nothing), so each side gets a model shaped for its job instead of one model straining to do both. Use when the user wants to represent each state-changing intent as a command object dispatched to a dedicated handler; the user wants distinct models for changing state and for reading data because one shared model has become awkward for both; the user wants read models tailored to each view, bypassing the write model to return exactly what a screen needs. Keywords: cqrs, command, read-model, write-model, separation, handler.
3 other projects use a version of this.
Adopted by
Most recently taken up by
- TheBeardedBearSAS/claude-crafttheir own version, first seen Oct 29, 2026
- troskater/flowdeck-claudetheir own version, first seen Oct 25, 2026
- G1Joshi/Agent-Skillstheir own version, first seen Oct 13, 2026
Other versions3 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 3
- TheBeardedBearSAS/claude-craft★ 108same name
- G1Joshi/Agent-Skills★ 15same name
- troskater/flowdeck-claude★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository119 other files it gives its agents.
- strategy-bitrix-d7-incrementalSkill
- strategy-explicit-over-magicSkill
- strategy-framework-conventionsSkill
- strategy-legacy-safe-editsSkill
- strategy-minimal-diffSkill
- strategy-no-untested-refactorSkill
- strategy-preserve-public-apiSkill
- strategy-readonly-immutabilitySkill
- strategy-security-firstSkill
- strategy-test-drivenSkill
- openapiSkill
- paginationSkill
- rest-designSkill
- versioningSkill
- dependency-inversionSkill
- hexagonalSkill
- repository-patternSkill
- service-layerSkill
- bitrixSkill
- findings-reportSkill
- laravelSkill
- performanceSkill
- phpSkill
- project-analysisSkill
- refactoringSkill
- roi-prioritizationSkill
- securitySkill
- stack-detectionSkill
- cache-layersSkill
- component-engineSkill
- d7-eventsSkill
- d7-loaderSkill
- d7-orm-queriesSkill
- iblock-elementsSkill
- kernel-main-moduleSkill
- localizationSkill
- controllersSkill
- ormSkill
- validationSkill
- controllersSkill
- query-builderSkill
- routingSkill
- autoload-psr4Skill
- dependency-managementSkill
- scriptsSkill
- connection-poolingSkill
- mysql-indexingSkill
- redisSkill
- transactionsSkill
- ci-github-actionsSkill
- deployment-strategiesSkill
- docker-phpSkill
- env-configSkill
- associationsSkill
- entities-mappingSkill
- orm-basicsSkill
- entity-apiSkill
- module-developmentSkill
- routing-controllersSkill
- formsSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 3 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 64
Do not adopt event sourcing or eventual consistency just because you are separating reads from writes.
- Distinctive: line 65
Do not split reads and writes for a plain CRUD screen where one model serves both sides comfortably.
- Distinctive: line 123
Not applicable — no I/O, auth, or untrusted input.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
<!-- generated: do not edit — source: knowledge/atoms/architecture/cqrs/ --><!-- schema: atomVersion=3 skillVersion=2 graphVersion=1 --><!-- compile: @php-skills/compiler v1.0.0 (deterministic build) -->CQRS (Command Query Responsibility Segregation)
When to use
- The user wants to represent each state-changing intent as a command object dispatched to a dedicated handler.
- The user wants distinct models for changing state and for reading data because one shared model has become awkward for both.
- The user wants read models tailored to each view, bypassing the write model to return exactly what a screen needs.
When NOT to use
- Do not adopt event sourcing or eventual consistency just because you are separating reads from writes.
- Do not split reads and writes for a plain CRUD screen where one model serves both sides comfortably.
Core guidance
- Make commands change state and return nothing — Let a command express an intent to change state and return
void(or only an identifier); never return the queried result of the change from the command handler. - Make queries return data with no side effects — Let a query return data and change nothing observable; a query handler must never write to the store or mutate domain state.
Quick recipe
- Define an immutable command carrying the intent's data (e.g.
final class RenameCustomer) and a handler whosehandle()applies the change and returnsvoid. (verify: The handler mutates state and returns nothing beyond an optional new id) - Define a query (e.g.
final class CustomerProfile) and a handler returning a view-shaped read model DTO with no side effects. (verify: The query handler only reads and returns data the screen needs) - Route commands and queries through a small dispatcher (or the framework's message bus) that maps each message to its single handler, registered at the composition root. (verify: Dispatching a command invokes only its handler; dispatching a query returns its read model)
Best practices
- Route each command or query message to exactly one handler dedicated to it, rather than a service with many mixed methods
- Build read models as flat, view-shaped DTOs that a query returns directly, rather than loading the write-side aggregate and reshaping it in the controller
- Separate the command and query models in code first while both read from the same database; only introduce a separate read store when a measured need justifies it
Anti-patterns
| Anti-pattern | Why it fails | Do instead |
| A command that also queries and renders | A handler that both writes and reads recreates the mixed model CQRS removes, so the two responsibilities re-entangle and testing gets harder. | Keep the command handler to applying the change, and put any read shaping in a separate query<br>handler the caller invokes next. |
| A query handler that writes to the store | A read that secretly writes breaks the guarantee that queries are safe to cache and retry, and hides state changes on the read path. | Move any needed write into an explicit command, and keep the query handler purely returning<br>data. |
| Naming it CQRS but sharing one model | If both sides depend on the same mutable model, nothing is actually segregated and the pattern's clarity and independence are absent. | Give the write side its aggregate and the read side its own view-shaped model, even when they<br>read from the same database today. |
See references/anti-patterns.md.
Common mistakes
- A command handler that returns the read result — Returning the full updated entity from a command handler so the caller can render it merges the write and read responsibilities the split was meant to keep apart. Fix: Return at most a new identifier from the command, then issue a separate query to fetch the read model for display.
- Surprising staleness from an async read model — Updating the read model asynchronously and then reading it immediately after a command can show stale data, confusing users who expect their change to appear at once. Fix: Keep the read model synchronous until you truly need async, and where it is async, signal the pending state in the UI or read from the write side for the just-changed record.
- Applying CQRS to every corner of the app — Forcing commands, queries, handlers, and read models onto simple lookups and settings screens buries trivial features under ceremony. Fix: Apply CQRS to the bounded contexts with real read/write asymmetry, and let simple areas keep a plain shared model.
Version notes
- Immutable messages with PHP 8.1 readonly (PHP >=8.1) — PHP 8.1 readonly promoted properties let commands and queries be defined as immutable data carriers in a couple of lines, reinforcing that a message is a fixed request.
- Typed class constants aid message metadata in PHP 8.3 (PHP >=8.3) — From PHP 8.3, typed class constants let a command or read model declare stable metadata (a message name or version) with an enforced type on the message class.
Security
- Not applicable — no I/O, auth, or untrusted input.
Testing
- Activation and decision behavior are verified in
eval/scenarios/architecture/cqrs.yaml.
Additional resources
- references/anti-patterns.md
- references/core.md
- references/examples.md
- references/pitfalls.md
- references/recipes.md
- references/version-differences.md
Knowledge graph
Related: architecture/hexagonal, architecture/service-layer
<!-- graph-fragment: graph/fragments/architecture/cqrs.yaml -->Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

