Problem
Frameworks, UIs, and databases dictate the shape of code, making business rules hard to test and expensive to migrate. Changes in outer technology ripple into core logic.
Also known as: onion-architecture, concentric-layers
Organize code in concentric layers where source dependencies only point inward toward business rules.
Frameworks, UIs, and databases dictate the shape of code, making business rules hard to test and expensive to migrate. Changes in outer technology ripple into core logic.
Clean architecture, popularized by Robert C. Martin, unifies earlier ideas such as hexagonal and onion architectures. Its single governing principle is the dependency rule: source code dependencies point only inward.
Each ring has a clear responsibility. Entities hold rules that would hold across the enterprise. Use cases orchestrate entities to fulfil a single application goal. Adapters convert data between use case format and the format of the web, database, or external systems. The outermost ring holds frameworks and glue.
Frameworks / Drivers
Interface Adapters (controllers, presenters, gateways)
Use Cases (interactors)
Entities
A use case declares an output boundary interface; the presenter in an outer ring implements it. This is dependency inversion, which lets control flow go outward while source dependencies go inward.
interface UserGateway { byId(id: string): Promise<User> }
class ChangeEmail {
constructor(private users: UserGateway) {}
async run(id: string, email: string) { /* domain logic */ }
}
None — code structure only
Low — no runtime cost
Medium to high — many layers and rules
Layer skipping, where controllers call repositories directly
Anemic entities, leaving rules scattered in use cases
Mapping explosion that slows every change