Hexagonal architecture — also called ports and adapters — organizes an application so that its core business logic has no direct dependency on any specific database, framework, UI, or external service. Instead, the core defines "ports" (interfaces describing what it needs), and swappable "adapters" implement those ports for a specific technology. The hexagon shape in diagrams is arbitrary; the point is that the business logic sits in the middle, isolated, with everything external plugged in around the edges.
What changed in 2026
- The pattern kept growing in adoption alongside AI-assisted development, since a clean separation between business logic and framework code made it far easier for AI coding tools to safely regenerate or modify one layer without touching the other.
- Framework authors (in Spring, NestJS, and various Go and Rust web frameworks) added more first-class scaffolding for ports-and-adapters style projects, reducing the boilerplate cost that used to make the pattern feel heavyweight for small projects.
- The pattern converged further in common usage with "clean architecture" and "onion architecture," with most teams treating the three as close variations on the same core idea rather than meaningfully distinct approaches.
Ports and adapters, concretely
A "port" is an interface the application core defines and depends on — for example, a UserRepository interface with methods like save and findById, with no mention of SQL, Postgres, or any specific database. An "adapter" is a concrete implementation of that port — a PostgresUserRepository class that actually runs SQL queries, or an InMemoryUserRepository used in tests. The core code calls the interface; it never imports or knows about the concrete adapter. Adapters exist for both driving the application (an HTTP controller calling into the core) and being driven by it (the core calling out to a database or an external API).
Hexagonal vs a typical layered app
| Aspect |
Traditional layered app |
Hexagonal architecture |
| Business logic dependency on framework |
Often tightly coupled (ORM models double as domain models) |
Business logic has zero framework dependency |
| Swapping the database |
Usually requires touching business logic |
Requires only writing a new adapter |
| Testing business logic |
Often requires a real or mocked database/framework |
Can test the core in isolation with fakes, no framework needed |
| Learning curve |
Lower, more familiar to most developers |
Higher - more interfaces and indirection upfront |
| Best for |
Small apps, simple CRUD, short-lived projects |
Complex domain logic, long-lived systems, systems expecting to swap infrastructure |
When it is worth adopting
Hexagonal architecture earns its complexity when business logic is genuinely complex and long-lived, or when you realistically expect to swap infrastructure — a different database, a new payment provider, a new external API — over the application life. For a simple CRUD app with thin business logic (see what is CRUD for the baseline this pattern is deliberately built to outgrow), the extra interfaces and indirection are often pure overhead with no corresponding benefit.
Common mistakes
- Applying it to a simple CRUD app where the added indirection has no real payoff, since there is no meaningful business logic to protect from framework coupling.
- Leaking framework types into the core anyway. Defining a port but then having its interface signature depend on a framework-specific type defeats the purpose of the boundary.
- Over-engineering the number of ports. Not every method needs its own interface; group related operations into cohesive ports that mirror real use cases.
- Skipping tests on the core because it is "just business logic." The entire point of the isolation is that the core should be the easiest, fastest part of the system to test — skipping that misses the main benefit.
FAQ
Is hexagonal architecture the same as clean architecture?
They are closely related, both built around the same core idea — business logic isolated from frameworks and infrastructure via interfaces. Clean architecture adds more prescriptive layering (entities, use cases, interface adapters); hexagonal is looser about internal structure, focused mainly on the ports-and-adapters boundary.
Does hexagonal architecture require microservices?
No. It is an internal structuring pattern for a single application or service, independent of whether that service is a monolith or one of many microservices.
Is this overkill for a small project?
Often, yes. The pattern pays for itself in complex, long-lived domains. A small internal tool or a straightforward CRUD app rarely needs the extra interfaces and adapter layers.
How does this relate to domain-driven design?
They pair naturally. Domain-driven design, covered in domain-driven design basics, focuses on modeling the business domain accurately; hexagonal architecture provides the structural boundary that keeps that domain model free of infrastructure concerns.
Where to go next