Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Lean architecture is a change-oriented way to structure software: keep business rules at the center, limit unnecessary coupling, and add layers only when they protect the domain or make meaningful change easier. Its closest established patterns are Clean Architecture and hexagonal architecture, also called ports and adapters. The key is not to maximize layers; it is to keep infrastructure replaceable without making the business logic depend on it.

What is lean architecture?

Here, “lean architecture” describes an architectural approach, not a single formal standard with one required diagram or folder structure. It aims to make software easier to change by centering the business domain and keeping details such as databases, user interfaces, frameworks, and external services at the edges.

This idea is closely related to hexagonal architecture. AWS describes hexagonal architecture as isolating an application core from external modules: ports define how the core interacts with the outside world, and adapters implement those interactions. Clean Architecture expresses a similar separation through concentric layers and a rule about dependency direction.

How is it different from Clean or hexagonal architecture?

These terms overlap, but they emphasize different ways of describing the same family of design concerns. Lean architecture, as used here, is the goal of keeping the structure as simple as possible while still supporting change. Hexagonal architecture makes the boundary explicit through ports and adapters. Clean Architecture describes boundaries as layers and emphasizes which way source-code dependencies may point.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Approach Emphasis Practical interpretation
Lean architecture Change-oriented simplicity Keep the business core independent, adding structure only when it earns its cost.
Hexagonal architecture Ports and adapters Define core-owned interfaces for external interactions; implement them in adapters.
Clean Architecture Concentric layers and dependency direction Organize code so dependencies point toward the inner business rules.

Robert C. Martin states the Clean Architecture Dependency Rule plainly: “Source code dependencies can only point inward.” In practical terms, a use case may depend on an interface it needs, but it should not import a concrete database client or UI framework. An outer component can implement the interface and be wired to the core at runtime. Martin develops this model in The Clean Architecture; his book, Clean Architecture: A Craftsman’s Guide to Software Structure and Design, is a direct reference for the layer model.

What should depend on what?

The domain and use cases should define the rules and the interfaces they need. External code depends on those interfaces by implementing them; the core does not depend on the external implementation. This is dependency inversion: the direction of source-code dependencies stays toward the business policy even when execution crosses outward to a database, service, or user interface.

  • Core: business entities, value objects, aggregates, and use cases. Keep these independent of infrastructure libraries.
  • Ports: interfaces describing the input the application accepts and the outputs or external capabilities it requires.
  • Primary adapters: entry points that translate requests from users, APIs, events, or functions into calls to the core.
  • Secondary adapters: implementations that connect core-defined output ports to databases or external services.

“Primary” and “secondary” describe the direction of interaction, not importance: primary adapters initiate work in the application, while secondary adapters provide capabilities the application calls. The application’s business rules should not know whether a particular port is implemented with a SQL database, a web service, or another technology.

When are ports and adapters worth the extra code?

Use explicit ports and adapters when the separation protects important business logic or makes likely change manageable. AWS identifies complex domains, multiple clients or integrations sharing the same logic, and interfaces or databases expected to change as situations where hexagonal architecture can fit. Its guidance also notes the costs: more complexity, adapter maintenance, and possible latency.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Situation Likely choice Reason
Complex domain rules, or several clients and integrations using the same logic Use clear ports and adapters The boundary keeps shared business rules separate from each delivery mechanism or external system.
Database, interface, or external-service technology is likely to change Use ports around the volatile boundary Replaceable adapters can limit how much core code a technology change affects.
Small, stable component with one input and one output Prefer a simpler structure unless a concrete change or testing need justifies more Adapter code and additional indirection may cost more to maintain than they save.

Do not add an interface for every class by default. A port is useful when it marks a meaningful boundary—such as a dependency the use case needs, an integration likely to change, or a seam needed to test behavior independently. If a boundary has no likely change, reuse, or testing benefit, the extra abstraction may be ceremony rather than protection.

How to design a lean architecture

  1. Start with the business problem and bounded context. Identify what the system is responsible for before organizing code around database tables or framework folders. Domain modeling and event storming can help surface the language, events, and boundaries of the problem.
  2. Model the core. Define the relevant entities, value objects, aggregates, commands, events, and use cases. Keep business rules in this model rather than embedding them in controllers, ORM models, or framework callbacks.
  3. Identify required interactions. For each use case, ask what input it needs and what external capabilities it must call. Define ports for those boundaries as core-owned interfaces, without importing infrastructure libraries into the core.
  4. Implement adapters at the edges. Add primary adapters for delivery mechanisms such as users, APIs, events, or functions, and secondary adapters for databases and external services. Translate between the outside format and the core’s model at these boundaries.
  5. Test behavior and automate delivery. Write unit and behavior tests early. AWS notes that hexagonal architecture makes independent testing possible without relying on data stores or UIs, and that the pattern can make test-driven development easier. Automate tests and deployment in CI/CD.
  6. Review the structure against its costs. Compare dependency direction, test isolation, expected technology change, number of integrations, operational latency, and adapter maintenance. Keep a boundary when its benefits justify its complexity.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

What are the benefits and trade-offs?

Benefits

  • Replaceable infrastructure: databases, interfaces, and service integrations can change without making the domain depend on their libraries.
  • More isolated tests: core behavior can be tested without requiring a live UI or data store, when its ports are implemented with suitable test doubles.
  • Shared rules across entry points: several clients can call the same use cases rather than duplicating business logic in each interface.

Trade-offs

  • More structure to understand: ports, adapters, and dependency wiring add concepts and indirection.
  • Adapter maintenance: each external integration has code that must be built and maintained.
  • Possible latency: added indirection or integration steps can affect runtime behavior; measure the actual system rather than assuming the pattern is free.

There is no established numeric guarantee that adopting lean, Clean, or hexagonal architecture reduces defects or delivers a particular return on investment. The rationale is architectural: separation can make change and testing easier, while its value depends on the domain and the boundaries a system actually has.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.