domain-driven-design
Skill4 starsChanged 8 months agoUnlicenseView on GitHub
Business complexity, model language, lifecycle rules, or cross-team/system boundaries shape the design more than generic technical organization. Synthesized from Domain-Driven Design (Evans), DDD Distilled (Vernon), and Implementing DDD (Vernon). Covers: strategic design (Bounded Contexts, Context Mapping, Subdomains), tactical patterns (Entities, Value Objects, Aggregates, Domain Events, Repositories, Factories), Ubiquitous Language discipline, integration patterns (Anticorruption Layer, Open Host Service), and when DDD is overkill. Triggers on: "DDD", "domain model", "bounded context", "aggregate", "ubiquitous language", "context mapping", "anticorruption layer", "domain event", "subdomain", or when modeling complex business domains.
We split this skill into the rules it gives an agent
30 rules. 0 are common, 27 are distinctive, and 3 are very specific to this project.
0
Common
Most of the 22 edited versions we read keep these.
27
Distinctive
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 19
If you are reading this, the user is working on a system where business complexity, language, or boundaries matter more than generic …
- Distinctive: line 25
Do not let persistence, UI, frameworks, integration formats, or DDD vocabulary replace an implementation-driving model.
- Distinctive: line 53
Every meaningful model gets one explicit Bounded Context.
- Distinctive: line 78
Use when identity and lifecycle matter.
- Distinctive: line 84
Use for immutable descriptive concepts where identity doesn't matter.
- Distinctive: line 90
Use as immediate consistency boundaries for invariants.
- Distinctive: line 92
Root-protected: All invariant-changing behavior goes through the root.
- Distinctive: line 94
One per transaction: Default to modifying one Aggregate per transaction.
- Distinctive: line 98
Use for meaningful past-tense business facts.
- Distinctive: line 101
Do NOT publish for every field change.
- Distinctive: line 108
Keep business rules out of repository implementations.
- Distinctive: line 112
Use when constructing an Aggregate requires multi-step validation or assembly.
- Distinctive: line 116
Use for domain-significant operations that involve multiple domain objects and don't fit naturally on any single Entity or Value Object.
- Distinctive: line 117
Keep technical transformation, serialization, transport, and persistence mapping OUT of the domain model.
- Distinctive: line 127
Application Services must NOT become the real domain model: If they accumulate branching business rules, move the decisions into the domain …
- Distinctive: line 139
When terminology is awkward, ambiguous, or inconsistent — pause coding and sharpen the language first.
- Very specific: line 144
Anticorruption Layer: When integrating with a messy/legacy/external model, add a translation layer before modeling locally.
- Very specific: line 161
Avoid giant shared or common packages for domain concepts.
- Distinctive: line 165
Only when the event sequence is the right persistence model:
- Distinctive: line 177
Ambiguous terminology: When a term is fuzzy, overloaded, or imported from another context — sharpen the Ubiquitous Language before coding.
- Distinctive: line 178
Cross-context coupling: When code wants to import another context's domain package or share enums — add explicit translation instead.
- Very specific: line 179
Foreign model leakage: When legacy/vendor/API/persistence shapes appear in domain code — add an Anticorruption Layer.
- Distinctive: line 180
Large Aggregate: When one transaction wants multiple Aggregates — list the invariants that require it.
- Distinctive: line 181
Anemic domain: When Application Services or controllers accumulate branching business rules — move decisions into domain objects.
- Distinctive: line 182
Primitive-carried rules: When a primitive, flag, status code, boolean, or enum carries domain rules — promote it to a richer concept or …
- Distinctive: line 183
Awkward conditionals: When new requirements force awkward conditional logic — search for a deeper model or missing implicit concept instead …
- Distinctive: line 184
Generic Repository: When a Repository becomes table-shaped or starts enforcing business rules — reshape around Aggregate access.
- Distinctive: line 185
Noisy events: When an event reads like a command, exposes framework artifacts, or describes a minor property change — rename, narrow, or …
- Distinctive: line 186
Representation pressure: When client rendering or query speed pressures the model shape — use projections, DTOs, or adapters instead of …
- Distinctive: line 187
Simple subdomain: When a subdomain is simple CRUD — keep it simple.
“Common” is measured: kept by at least 6 in 10 of the 22 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Domain-Driven Design
When This Skill Loads
If you are reading this, the user is working on a system where business complexity, language, or boundaries matter more than generic technical organization. Model the domain first. Let the code follow the model.
Core Principle
Keep domain behavior, code, tests, documents, and team language aligned inside explicit Bounded Contexts.
Do not let persistence, UI, frameworks, integration formats, or DDD vocabulary replace an implementation-driving model.
When DDD Is Warranted
Any one of these justifiers is sufficient to warrant strengthening the model:
- Business rules are complex (not just CRUD)
- Domain experts use specific terminology that differs from technical terms
- Multiple teams or systems share data but have different conceptual models
- The same word means different things in different parts of the business
- Invariants and lifecycle rules are non-trivial
- Integration with external/legacy systems requires translation
When DDD is overkill: Simple CRUD, generic subsystems, or mainly technical problems. Use the lightest approach that works.
Strategic Design
Subdomains
Classify every business capability:
| Type | What it is | Modeling effort |
| Core Domain | Competitive advantage, strategic differentiation | Highest — rich model, best people, most iteration |
| Supporting | Needed for the business, but not a differentiator | Moderate — model honestly, but don't over-invest |
| Generic | Commodity (auth, notifications, logging) | Lowest — buy/build simple, no custom modeling |
Bounded Contexts
Every meaningful model gets one explicit Bounded Context. The context owns:
- Its language (Ubiquitous Language — one term per concept, one meaning per term)
- Its rules and semantics
- Its code structure, tests, and integration contracts
The same word in different contexts may mean different concepts. "Order" in billing is not "Order" in fulfillment. Translate at boundaries.
Context Relationships
Choose deliberately:
| Relationship | Meaning | When to use |
| Partnership | Teams coordinate closely, models evolve together | Same team, tightly coupled contexts |
| Shared Kernel | Small shared model, jointly owned and tested | Stable overlap both teams agree on |
| Customer/Supplier | Downstream depends on upstream; upstream prioritizes downstream's needs | Clear upstream/downstream dependency |
| Conformist | Downstream conforms to upstream's model exactly | No leverage to influence upstream |
| Anticorruption Layer (ACL) | Downstream translates upstream's model into its own language | Upstream model is messy, foreign, or legacy |
| Open Host Service (OHS) | Upstream provides a published protocol for multiple downstreams | Many consumers need standardized access |
| Published Language | Shared format (schema, API contract) for integration | Cross-organization or cross-team integration |
| Separate Ways | No integration; contexts are independent | No real dependency exists |
Tactical Patterns
Entities
Use when identity and lifecycle matter. An Entity is defined by its ID, not its attributes.
- Make identity explicit (e.g.,
OrderId, not a raw integer). - Protect meaningful state transitions — don't expose unrestricted setters.
- Methods should reveal domain purpose, not just change fields.
Value Objects
Use for immutable descriptive concepts where identity doesn't matter.
- Validate at construction — a Value Object is always valid.
- Compare by value, not by reference.
- Replace raw primitives for meaningful concepts:
Money,EmailAddress,DateRange.
Aggregates
Use as immediate consistency boundaries for invariants.
- Small. One root Entity, few internal objects. If it's large, the boundary is wrong.
- Root-protected. All invariant-changing behavior goes through the root.
- Identity-referenced. Reference other Aggregates by ID, not by object reference.
- One per transaction. Default to modifying one Aggregate per transaction. Use events for cross-Aggregate coordination.
- Hide internals. Mutable internals are not exposed to callers.
Domain Events
Use for meaningful past-tense business facts.
- Name in past tense:
OrderPlaced,PaymentReceived,ShipmentDelivered. - Payload is local to the model — don't leak foreign schemas.
- Do NOT publish for every field change. Events represent business significance.
- Consumers must tolerate lag, duplicates, and ordering limits.
Repositories
Provide access to Aggregate Roots, not tables.
- Define interfaces by domain needs, not by persistence mechanics.
- Return domain objects, not ORM rows or DTOs.
- Keep business rules out of repository implementations.
Factories
Hide complex creation logic.
- Use when constructing an Aggregate requires multi-step validation or assembly.
- Prevent partially formed objects from escaping.
Domain Services
Use for domain-significant operations that involve multiple domain objects and don't fit naturally on any single Entity or Value Object.
- Keep technical transformation, serialization, transport, and persistence mapping OUT of the domain model.
Application Services
Coordinate use cases:
- Load Aggregates (via Repositories)
- Invoke domain behavior (on Aggregates/Entities)
- Persist results
- Publish resulting Domain Events
- Own transaction/integration coordination
Application Services must NOT become the real domain model. If they accumulate branching business rules, move the decisions into the domain objects.
Refactoring Toward Deeper Insight
Refactor toward deeper domain insight, not only mechanical cleanliness. When a constraint, policy, process, or calculation carries domain meaning, make it an explicit named model concept instead of leaving it implicit in conditionals or helper code. If new behavior is hard to explain, test, or extend, a deeper model or missing implicit concept is usually waiting — find it rather than adding procedural branches.
Ubiquitous Language Discipline
- One concept gets one term inside a context.
- One term does not carry multiple meanings inside a context.
- Code, tests, commands, events, repositories, services, and packages must speak the local language.
- Rename code when understanding improves — don't let technical names drift from domain meaning.
- When terminology is awkward, ambiguous, or inconsistent — pause coding and sharpen the language first.
Integration and Translation
- Translate foreign models into the local language. Keep foreign schemas, statuses, and contract models out of local domain objects.
- Anticorruption Layer: When integrating with a messy/legacy/external model, add a translation layer before modeling locally.
- Keep integration contracts separate from internal models. Test translations wherever meanings cross a boundary.
- Integration style matters:
- RPC: Requires acceptable request/response coupling
- REST: Resources must not expose Aggregate internals
- Messaging: Must tolerate lag, duplicates, and ordering limits
Package Structure
Organize by Bounded Context first, then by domain or use-case ownership within the context:
context-name/
domain/ # Entities, Value Objects, Domain Events, Repositories (interfaces)
application/ # Application Services, DTOs, Command handlers
infrastructure/ # Repository implementations, messaging, persistence adaptersAvoid giant shared or common packages for domain concepts.
When to Use Event Sourcing
Only when the event sequence is the right persistence model:
- Audit trail is a first-class requirement
- Replay/reconstruction is a core feature
- The domain naturally thinks in terms of state transitions
Requirements:
- Streams match Aggregate identity and versioning
- Replay is deterministic
- Event meaning changes need versioning, upcasters, or translators
Trigger Rules
- Ambiguous terminology: When a term is fuzzy, overloaded, or imported from another context — sharpen the Ubiquitous Language before coding.
- Cross-context coupling: When code wants to import another context's domain package or share enums — add explicit translation instead.
- Foreign model leakage: When legacy/vendor/API/persistence shapes appear in domain code — add an Anticorruption Layer.
- Large Aggregate: When one transaction wants multiple Aggregates — list the invariants that require it. Otherwise coordinate by identity and events.
- Anemic domain: When Application Services or controllers accumulate branching business rules — move decisions into domain objects.
- Primitive-carried rules: When a primitive, flag, status code, boolean, or enum carries domain rules — promote it to a richer concept or Value Object.
- Awkward conditionals: When new requirements force awkward conditional logic — search for a deeper model or missing implicit concept instead of adding procedural branches.
- Generic Repository: When a Repository becomes table-shaped or starts enforcing business rules — reshape around Aggregate access.
- Noisy events: When an event reads like a command, exposes framework artifacts, or describes a minor property change — rename, narrow, or remove it.
- Representation pressure: When client rendering or query speed pressures the model shape — use projections, DTOs, or adapters instead of exposing Aggregate internals.
- Simple subdomain: When a subdomain is simple CRUD — keep it simple. Don't add DDD ceremony.
Final Checklist
- Bounded Context explicit before interpreting names, modules, events, repositories, APIs?
- One local term per concept across tests, commands, events, repositories, services, packages?
- Core Domain effort protected while supporting/CRUD areas stay simpler?
- Context relationships, translation responsibilities, and upstream/downstream pressures visible?
- Aggregates small, root-protected, invariant-driven, identity-linked, usually one per transaction?
- Entities behavior-bearing and Value Objects immutable, validated, and value-equal?
- Repositories are Aggregate-root access points, not generic DAOs or ORM leaks?
- Domain Events are meaningful past-tense facts, not noisy field-change notifications?
- Application Services coordinate use cases instead of owning domain decisions?
- Client, foreign, persistence, and infrastructure representations kept outside the domain model?
- Tests read like executable examples of the model and cover invalid transitions?
Reference
| File | Use When |
| Strategic Design | Defining Bounded Contexts, subdomains, and context relationships |
| Tactical Patterns | Choosing between Entities, Value Objects, Aggregates, Events, Repositories |
| Integration Patterns | Designing cross-context integration, ACL, OHS, published language |
| Application Architecture | Structuring Application Services, repositories, package organization |
Other versions23 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 23
- ciembor/agent-rules-books★ 2.8ksame name
- wondelai/skills★ 2.2ksame name
- rrezartprebreza/spring-boot-skills★ 325same name
- techygarg/lattice★ 209same name
- fatonh/symfony-skills★ 35same name
- d-padmanabhan/agent-engineering-handbook★ 17same name
- G1Joshi/Agent-Skills★ 15same name
- eralmansouri/skills★ 9same name
- bernard-ng/skills★ 4same name
- EvanOman/claude-skills-public★ 4same name
13 more not listed
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.
Used alongsideProjects with it also use hexagonal-architecture, clean-architecture and 2 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
ffsshhttiikkSkillhexagonal-architecture
Hexagonal architecture patterns and implementation
Also in 4 projects that use this
harrissohail6Skillclean-architecture
Clean architecture and SOLID principles. Auto-activates when designing systems or refactoring code structure.
Also in 4 projects that use this
xenitV1Skillclean-code
Pragmatic coding standards - concise, direct, no over-engineering, no unnecessary comments
Also in 4 projects that use this
SentrySkillreview
Fixture review skill.
Also in 3 projects that use this
In this repository73 other files it gives its agents.
- agent/AGENTS.mdAGENTS.md
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- git-guardrails-claude-codeSkill
- setup-project-skillsSkill
- skill-creatorSkill
- websearchSkill
- writing-great-skillsSkill
- codebase-designSkill
- construction-craftSkill
- critical-partnerSkill
- data-intensiveSkill
- diagnosing-bugsSkill
- django-disciplineSkill
- docker-disciplineSkill
- documentation-lifecycleSkill
- enterprise-patternsSkill
- git-disciplineSkill
- legacy-codeSkill
- production-readinessSkill
- refactoring-passSkill
- resolving-merge-conflictsSkill
- tddSkill
- testing-workflowSkill
- ui-design-directionSkill
- webapp-testingSkill
- writing-for-agentsSkill
- django-allauthSkill
- djangoSkill
- dockerSkill
- drfSkill
- full-calendarSkill
- giteaSkill
- htmxSkill
- http-status-codesSkill
- hyperscriptSkill
- langchainSkill
- litestarSkill
- prestashopSkill
- prSkill
- pykeSkill
- python-asyncSkill
- tablerSkill
- cleanroom-rewriteSkill
- councilSkill
- court-jesterSkill
- domain-modelingSkill
- fix-prSkill
- grillingSkill
- grill-meSkill
- grill-with-docsSkill
- handoffSkill
- humanifySkill
- implementSkill
- implement-specSkill
- improve-codebase-architectureSkill
- ponytail-auditSkill
- ponytail-debtSkill
- prototypeSkill
- qaSkill
- The first 60 shown.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
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.

