Clean Architecture
In short
Clean architecture is a way of structuring software in layers so that the core business rules never depend on frameworks, databases, or user interfaces.
What is clean architecture?
Clean architecture is a set of guidelines, popularized by software engineer Robert C. Martin in 2012, for organizing an application into concentric layers. At the center are entities, the core business rules; around them are use cases, which describe what the application does; then interface adapters such as controllers and repositories; and on the outside are frameworks and drivers such as the web framework, the database, and the UI.
The most important idea is the dependency rule: source code dependencies may only point inward. The business logic never imports the database library or the web framework; instead, it defines interfaces, such as OrderRepository, and the outer layers provide implementations of them. This is the Dependency Inversion Principle applied to a whole application, usually wired together with dependency injection.
An analogy is a house whose structure doesn't depend on its furniture: you can repaint the walls or replace the sofa without touching the load-bearing walls. In the same way, a team can switch databases, add a mobile app next to the web app, or test every business rule without a real database, because the core doesn't know those details exist.
Clean architecture is closely related to hexagonal architecture, also called ports and adapters, and to onion architecture, which share the same goal of keeping business logic independent of technology. It is not about clean code style, such as naming and formatting, and it is not free: the extra layers and interfaces add boilerplate, so small applications and prototypes often don't need the full structure.
Key takeaways
- Code is organized in layers: entities, use cases, interface adapters, and frameworks.
- The dependency rule: dependencies only point inward, toward the business rules.
- Business logic defines interfaces; outer layers implement them.
- The core can be tested without databases, frameworks, or a UI.
- The extra layers add boilerplate, so match the structure to the project size.
Example
// Inner layer: business rules that depend only on an interface they define
type Order = { id: string; total: number };
interface OrderRepository { save(order: Order): Promise<void> }
class PlaceOrder {
constructor(private orders: OrderRepository) {}
async execute(order: Order) {
if (order.total <= 0) throw new Error("Order total must be positive");
await this.orders.save(order);
}
}
// Outer layer: a database adapter implements that interface
class SqlOrderRepository implements OrderRepository {
async save(order: Order) { /* INSERT INTO orders ... */ }
}Readers ask
What is the dependency rule in clean architecture?
The dependency rule says code in an inner layer must never depend on anything in an outer layer. Business rules don't import framework or database code; instead, outer layers depend on interfaces that the inner layers define.
What is the difference between clean architecture and hexagonal architecture?
They share the same goal of isolating business logic from technical details. Hexagonal architecture describes this as a core surrounded by ports and adapters, while clean architecture adds more explicitly named layers such as entities and use cases.
Is clean architecture overkill for small projects?
Often, yes. For small applications or prototypes, the extra interfaces and layers can slow development without much benefit. Many teams start simpler and introduce clearer boundaries as the codebase and its business rules grow.
See also
- SOLIDSoftware Architecture, p. 42SOLID is a set of five object-oriented design principles that help developers write code that is easier to understand, extend, test, and maintain.
- Dependency InjectionSoftware Architecture, p. 12Dependency injection is a design technique in which an object receives the other objects it needs from the outside instead of creating them itself.
- Separation of ConcernsSoftware Architecture, p. 37Separation of concerns is a design principle that divides a program into distinct parts, each responsible for one clearly defined aspect of its behavior.
- Domain-Driven DesignSoftware Architecture, p. 15Domain-driven design is an approach to building software that models the code closely on the business domain, using the same language as the domain experts.
- MVCSoftware Architecture, p. 29MVC is an architectural pattern that splits an application into a Model for data and logic, a View for display, and a Controller that handles user input.
- Design PatternSoftware Architecture, p. 13A design pattern is a proven, reusable solution to a common problem in software design, described as a general template rather than as finished code.
Spotted a mistake or something missing on this page?Suggest an edit