# Domain-Driven Design vs Clean Architecture: What Is the Boundary Drawn Around?

> DDD draws boundaries around meaning — bounded contexts, ubiquitous language, aggregates. Clean Architecture draws them around dependency direction. How they compose, what each one does that the other cannot, and when DDD is genuinely overkill.

By Michał Jaskólski · Published 2026-08-18 · Updated 2026-08-18 · 9 min read
Canonical: https://skills.wondel.ai/learn/domain-driven-design-vs-clean-architecture/
Skills used: domain-driven-design, clean-architecture, software-design-philosophy, ddia-systems, 37signals-way

**TL;DR:** Both draw boundaries, around different things. Domain-Driven Design decides where a boundary belongs and what the words inside it mean — bounded contexts, ubiquitous language, aggregates. Clean Architecture decides which way dependencies cross it. They compose: DDD's domain layer is what sits in Clean Architecture's core. The recurring mistake is treating a bounded context as a layer.

- DDD answers where a boundary goes and what it means; Clean Architecture answers which way dependencies cross it. Neither answers the other's question.
- A bounded context is a vertical slice with its own full stack; a layer is horizontal. Conflating them gives you one shared model with four layers painted on it.
- The repository is where the two lock together: DDD names it in domain terms, Clean Architecture puts the interface inside the boundary and the implementation outside.
- Strategic DDD — contexts, ubiquitous language, core versus generic subdomains — is cheap and pays early. Tactical DDD is where the cost lands, and where small systems should usually stop.
- Hexagonal, Onion and Clean Architecture are a family sharing one instinct, not the same architecture — and none of them is DDD.

Both are boundary disciplines, and the conflation is expensive because the question each answers is different. Clean Architecture asks **which way dependencies may cross a boundary**. Domain-Driven Design asks **where the boundary belongs and what the words inside it mean**. You can satisfy one perfectly and have nothing to show for the other.

The tell is a team that says "bounded context" when it means "layer" — a mistake that yields one shared, overgrown model with a tidy stack of folders around it.

We publish both as free agent skills and they are among the most-installed pair in the library, so this is a composition question, not a contest. If the format is new to you, start with [what an AI agent skill is](https://skills.wondel.ai/learn/what-is-an-ai-agent-skill/).

## What does Clean Architecture draw its boundary around?

Dependency direction, and almost nothing else. [Clean Architecture](https://skills.wondel.ai/skills/clean-architecture/) turns on the Dependency Rule: source code dependencies may point only inward, toward higher-level policy, and an inner circle must not name anything declared in an outer one — no class, no function, no data format the outer layer owns. Entities innermost, use cases around them, adapters outside, frameworks at the edge. When control flows outward at runtime, you invert it with an interface declared on the inside.

That is a rule about *arrows*, and it is deliberately content-free: it has no opinion on whether the central object is an `Order` or a `TransactionRecord`, or whether billing and support share one customer model. Point every arrow correctly at a single overgrown model and you have a textbook-compliant architecture wrapped around the exact structure DDD exists to prevent.

## What does DDD draw its boundary around?

Meaning. [Domain-Driven Design](https://skills.wondel.ai/skills/domain-driven-design/) starts from the claim that the hard part is understanding the business, and that the code should say what the business says. Three ideas carry the weight.

**Ubiquitous language.** One vocabulary, used identically in conversation, in the model and in the code. When the words match, a whole class of translation bugs stops existing, and a domain expert can read a method name and tell you it is wrong.

**Bounded contexts.** A boundary inside which one word has exactly one meaning. `Customer` in billing carries a tax ID and a payment method; `Customer` in support carries a ticket history and a satisfaction score. Fusing them into one omniscient class is the failure the pattern exists to prevent. Where contexts meet you translate, often through an anti-corruption layer.

**Aggregates.** A cluster governed by a root that enforces the invariants, making it a transactional consistency boundary as well as a modelling one. Evans defined the root and the rule that outside objects reference only it; the familiar heuristics about small aggregates and referencing others by identity are later tightenings, most associated with Vaughn Vernon rather than the 2003 book.

Notice what DDD does not decide: whether the domain layer may import the ORM. Evans isolates the domain; the mechanism that *enforces* that isolation is Clean Architecture's contribution.

## DDD vs Clean Architecture: the boundary table

| | Domain-Driven Design | Clean Architecture |
|---|---|---|
| The question it answers | Where does the boundary belong, and what do the words mean inside it? | Which way may dependencies cross it? |
| Boundary shape | Vertical — a bounded context is a full slice of the system | Horizontal — layers within one deployable |
| Silent on | Which way dependencies point | What anything means or where to cut |
| Between systems | Context mapping: anti-corruption layer, conformist, shared kernel | An adapter, with no view on the relationship |
| Who must be in the room | Domain experts — it is a conversation before it is code | Developers — a decision you can make alone |
| Verified by | A domain expert reading the code and disagreeing | An import graph |
| Cheapest useful subset | The ubiquitous language | The direction rule at one volatile boundary |
| Cost when overapplied | Aggregates and mappers around a domain with no invariants | Circles, DTOs and interfaces around a CRUD app |

> Clean Architecture tells you which way the arrows point. Domain-Driven Design tells you what the boxes are called and why they exist.

## How do they compose in one codebase?

Cleanly, because DDD's domain layer is what Clean Architecture leaves empty at the centre. Martin's inner circle is a *slot*: it holds enterprise-wide business rules and says nothing about their shape, so a transaction script sitting there satisfies the Dependency Rule perfectly. DDD is the richest way to fill it — entities, value objects and aggregates that own their invariants.

The repository is where the two lock together. Evans's Repository already declares itself in domain language and hides the persistence technology; Martin's rule puts the interface inside the boundary and its Postgres implementation outside. Same object, two justifications. The anti-corruption layer works the same way: Clean Architecture calls it an adapter and stops, while DDD tells you what the translation is *for*.

The failure worth naming is confusing the two boundary shapes. A bounded context is vertical — its own model, its own language, its own full stack, potentially its own database. A layer is horizontal and lives *inside* a context. One `Customer` model with a controller, a service and a repository around it is layers, not contexts, and a fifth folder will not produce any.

> **Prompt** — Use the `domain-driven-design` skill to map the bounded contexts in my system — find the words that mean different things to different teams, draw the context map with the relationship type for each pair, and mark where an anti-corruption layer is needed so another team's model does not leak into mine
> (https://skills.wondel.ai/skills/domain-driven-design/)

## Is hexagonal architecture the same as Clean Architecture — and is either one DDD?

Related, not identical, and no.

Ports and Adapters (Alistair Cockburn, 2005), Onion Architecture (Jeffrey Palermo, 2008) and Clean Architecture (Robert C. Martin, 2012 as a post, 2017 as a book) are a family; Martin presents his as a synthesis and names the others as inputs. They share one instinct: the application core defines the interfaces, infrastructure implements them, and the source dependency points inward.

They differ in what else they prescribe. Hexagonal is deliberately symmetric — driving ports on one side, driven ports on the other — and says nothing about layering inside the hexagon. Onion adds concentric rings with a domain model at the centre. Clean Architecture adds the entity-versus-use-case split and a rule about what may cross a boundary.

None of them is DDD. The association is historical — Vaughn Vernon's *Implementing Domain-Driven Design* uses ports and adapters as its default architecture — but that is a pairing convention, not an identity. You can build a hexagon around a domain model nobody in the business would recognise.

## When is DDD overkill?

More often than its reputation suggests. The tactical half — aggregate roots, repositories, factories, value objects, an application layer, mapping between domain and persistence models — multiplies files and indirection, fights most ORMs, and needs a team fluent in the vocabulary. Against a domain with real invariants that is an excellent trade; against a form saved to a table it is ceremony, and an aggregate that enforces nothing is a class with a list inside it.

The guard is DDD's own strategic layer, which is the half people skip. Separate the core domain — the part that is actually your advantage — from the generic subdomains anyone could buy, model the core deeply, and buy authentication, email and payments rather than hand-crafting a commodity. If nothing qualifies as core, that is your answer about the tactical patterns.

Strategic DDD is a different bargain: naming things the way the business names them costs nothing, and noticing that `Customer` means two things is worth doing on day one, when the split is a rename rather than a migration. It is the aggregate machinery that has to justify itself — [The 37signals Way](https://skills.wondel.ai/skills/37signals-way/) is the counterweight when it cannot.

> **Prompt** — Use the `clean-architecture` skill to take the domain model I already have and place it under the Dependency Rule — say which types are entities and which are use cases, where each repository interface should be declared versus implemented, and exactly what is allowed to cross each boundary
> (https://skills.wondel.ai/skills/clean-architecture/)

## Which one do you need first?

Stop at the first line that matches.

1. **Two teams use the same word for different things and the translation keeps producing bugs.** DDD, strategic half.
2. **You cannot run a business rule in a test without the database and the web framework.** Clean Architecture. Your model is not the problem yet.
3. **One class has forty fields because three departments each needed six.** DDD — a missing context boundary, not a missing layer.
4. **You are about to split into services.** DDD first to find the seams, Clean Architecture second for the inside of each one. Splitting before you know the seams is the expensive order.
5. **The domain is genuinely CRUD and every word means one thing.** Keep the direction rule and the ubiquitous language; skip the tactical patterns. If the modules are multiplying anyway, that is a complexity question for [Software Design](https://skills.wondel.ai/skills/software-design-philosophy/).

## Frequently asked questions

### Is a bounded context the same as a layer?

No, and it is the most consequential confusion of the two. A bounded context is a vertical slice — its own model, its own language, its own stack of layers, potentially its own database. A layer is horizontal and sits inside a context. Layers separate technical responsibilities within one model; contexts separate models from each other.

### Do I need DDD to use Clean Architecture?

No. Clean Architecture works over any core, including procedural transaction scripts — the Dependency Rule is satisfied by placement alone. What you lose is a principled answer to where the boundaries go, which is why systems with a clean layer diagram and one enormous shared model are so common.

### Are aggregates, domain events and CQRS all part of DDD?

Aggregates are, from the 2003 book. Domain events entered the pattern language later, and CQRS and event sourcing grew up alongside DDD rather than inside it — commonly paired, not required. Treat the tactical catalogue as a menu you order from once strategic design says the domain is worth it.

### Which should I learn first?

Clean Architecture, for the faster payback: one rule, verifiable in an import graph, useful on the smallest project. DDD earns its keep when people already argue about what things mean — and if that is happening now, invert the order, because no amount of correct dependency direction settles an argument about what `Customer` is.

## Where to go next

If your question is craft rather than boundaries, the neighbouring comparison is [Clean Code vs Clean Architecture](https://skills.wondel.ai/learn/clean-code-vs-clean-architecture/). Applied from scratch, in sequence: [how to design the best possible architecture for a new app](https://skills.wondel.ai/guides/design-the-best-architecture-for-a-new-app/).

Both skills are free and MIT-licensed, alongside the rest of the [Architecture & Systems skills](https://skills.wondel.ai/skills/architecture/):

```
npx skills add wondelai/skills --all --global
```
