Onion Architecture, Clean Architecture, and Hexagonal Architecture are often used interchangeably in job descriptions and blog posts. Structurally, how does Onion Architecture relate to the other two, and what does it actually add or change relative to a plain layered architecture?
answer
- Hexagonal (Cockburn ~2005): ports/adapters, oldest
- Onion (Palermo 2008): concentric rings, domain vs app services
- Clean (Martin 2012/2017): adds explicit use-case layer + boundary models
- all three: same inward dependency rule, different vocabulary
- vs plain layered: layered lets business layer import data-access types directly
basics
~20 sAll three put business rules in the middle and infrastructure on the outside, with dependencies pointing inward — they're basically siblings with different names for similar ideas. Onion Architecture is the one that talks about rings (domain, domain services, application services, infrastructure); the others use different vocabulary for similar ideas.
solid answer
~60 sOnion Architecture (Palermo, 2008) is one of three well-known formulations of 'dependencies point inward, business logic at the center.' It defines the rings explicitly: domain model, domain services, application services, then outer infrastructure/UI. Hexagonal Architecture (Cockburn, roughly 2005) frames the same inward-dependency idea as ports (interfaces the application core defines) and adapters (implementations that plug into those ports from the outside), emphasizing symmetry between adapters driving the core and adapters the core drives, without prescribing internal ring structure. Clean Architecture (Martin, 2012) is largely a synthesis that adds an explicit use-case layer as the organizing unit of the application ring and is more prescriptive about boundary-crossing mechanics. All three agree on the same core dependency rule; they differ mainly in vocabulary and in which structural detail they emphasize. Practically, the difference matters less than the underlying discipline — a codebase can honestly claim 'Onion' and still borrow Clean's use-case naming or Hexagonal's port/adapter vocabulary, and interviewers rarely care which label you use as long as you can explain and enforce the dependency rule itself.
go deeper
Should recognize that these are three names for a similar idea (business logic at the center, dependencies point inward) without needing to know origins or fine distinctions.
Should be able to name at least one structural detail unique to each (rings vs ports/adapters vs use-case layer) even if fuzzy on exact history.
Should be able to explain the shared dependency rule precisely and correctly attribute at least the rough distinguishing idea of each (Hexagonal = ports/adapters symmetry, Onion = ring naming for domain vs app services, Clean = explicit use-case layer).
Should be able to navigate a team or job-posting's loose, non-textbook usage of these labels, focus discussion on the underlying dependency-rule discipline rather than terminology purity, and make a call on which vocabulary to standardize on for a given team without treating it as a technical decision of consequence.
## Why the three get confused The confusion between Onion, Hexagonal, and Clean Architecture is understandable because they were developed independently by different authors over roughly a decade, converged on the same core insight, and are now frequently cited together or even used as synonyms in industry job postings — but they do have distinct origins and distinct emphases, and understanding both the commonality and the differences is useful for reading unfamiliar codebases and for not getting tripped up by terminology mismatches in an interview or design review. ## Hexagonal — ports and adapters **Hexagonal Architecture**, introduced by Alistair Cockburn around 2005, is the oldest of the three. Its central metaphor is the hexagon (chosen mainly to avoid implying a fixed number of sides or a top/bottom, unlike a traditional layered diagram) with the application's core logic in the middle and **'ports'** — interfaces the core defines for what it needs from, or offers to, the outside world — around its edges. **'Adapters'** are the concrete implementations that plug into those ports from the outside: - a REST controller is a 'driving' or 'primary' adapter that calls into the core through an inbound port; - a database repository implementation is a 'driven' or 'secondary' adapter that the core calls out to through an outbound port. Hexagonal's emphasis is on this symmetry — the same architectural mechanism explains both how an HTTP request reaches the core and how the core reaches a database — and on adapters being swappable and testable in isolation. ## Onion — concentric rings **Onion Architecture**, coined by Jeffrey Palermo in 2008, shares the same inward-pointing dependency rule but presents it as a series of concentric rings rather than a hexagon with ports on its edges: - domain model at the absolute center; - domain services around that; - application services around that; - and infrastructure/UI as the outermost ring. Its distinguishing contribution is naming and separating domain services from application services explicitly as two different rings with two different responsibilities (pure cross-entity business rules versus use-case orchestration), which Hexagonal's port/adapter framing doesn't call out as separate concepts — Hexagonal is largely agnostic about how the core itself is internally organized, as long as ports mediate the boundary. ## Clean — the explicit use-case layer **Clean Architecture**, popularized by Robert C. Martin in a 2012 blog post and later a 2017 book, is best understood as a synthesis and refinement of the two ideas above, adding one significant organizing concept: **use cases as the explicit unit of the application layer**, each one representing a single thing the system can do, often paired with dedicated input/output boundary objects so that data crossing a layer boundary is always a plain, layer-owned model rather than a domain entity or an infrastructure model leaking through. Clean Architecture's diagram uses four rings (Entities, Use Cases, Interface Adapters, Frameworks and Drivers) and is more prescriptive than either Onion or Hexagonal about exactly how data should be shaped when it crosses a boundary. In practice, 'Clean Architecture' in casual industry usage often just means 'onion/hexagonal with an explicit use-case layer,' since that's the one concrete addition most teams actually adopt from Martin's formulation. ## The one rule they share What all three share, and what actually matters for a working engineer far more than the label, is a single underlying rule: **dependencies point inward**, from concrete/volatile outer layers toward abstract/stable inner layers, and the core business logic has zero awareness of frameworks, databases, or delivery mechanisms. What differs between them is mostly vocabulary and which structural detail gets a name: | Formulation | What it contributes | |---|---| | Hexagonal | names the boundary mechanism but stays quiet about internal core structure | | Onion | names the internal core structure but is looser about adapter symmetry | | Clean | adds the use-case-as-unit-of-organization idea and boundary-model discipline on top of both | ## Against a plain layered architecture Relative to a plain N-tier layered architecture (UI to business logic to data access, with each layer freely depending on the one 'below' it, and often the data access layer's model reused directly as the business layer's model), all three add the same thing: an explicit inversion so that the innermost logic doesn't depend on the outermost technology, rather than a layered architecture's typical arrangement where the business layer directly imports and depends on data-access types. In interviews and design reviews, this means the useful skill is being able to say 'I mean dependencies point inward, ports/interfaces owned by the core, and here's specifically how I'd structure the internal rings' rather than defending one label as uniquely correct — real codebases routinely mix the vocabulary without contradiction, because the underlying discipline is identical.
- If a job posting says 'we use Clean Architecture' but the codebase has no explicit use-case/interactor classes, is that a red flag?Not necessarily a red flag on its own — 'Clean Architecture' is used loosely in industry to mean any onion/hexagonal-style inward-dependency design, and plenty of teams use the label without adopting Martin's specific use-case-object convention. It's worth asking what they actually mean structurally rather than assuming a strict textbook implementation, since the label-to-implementation mapping varies a lot team to team.
- What single question would you ask to check whether a codebase actually follows any of these three patterns, regardless of which name the team uses?Whether the core business logic module can be compiled and unit-tested with zero infrastructure dependencies on its classpath — no ORM, no HTTP client, no framework annotations. That single test cuts through vocabulary differences and checks the one rule all three patterns actually share: the inward-only dependency direction.
- Does adopting Hexagonal Architecture's port/adapter language instead of Onion's ring language change anything structurally?Not fundamentally — a repository interface in Onion terms and an 'outbound port' in Hexagonal terms are the same mechanism described with different words, and a controller calling into an application service is the same as an 'inbound port' being driven by a 'primary adapter.' The practical difference is mainly which structural detail the team chooses to name and standardize on, not a different dependency rule.
Like three engineers independently inventing the seatbelt — one calls it a 'harness,' one calls it a 'restraint system,' one adds a specific buckle mechanism — they're differing on naming and one added detail, not on whether you should be strapped in.
saying these in an interview costs you the question
- Claims Onion, Hexagonal, and Clean are completely unrelated patterns
- Can't state the one dependency rule all three share
- Insists there's a strict, universally agreed set of layers with no vocabulary overlap in real usage
- Doesn't know any of the three original authors or rough timeframes
- Treats the choice of label as more important than whether the dependency rule is actually enforced in the code