Which Architecture Style When?
A side-by-side comparison of layered, Clean, Hexagonal, Onion, Vertical Slice, Modular Monolith, Plugin and microservices, with criteria, ratings, scenarios and a decision procedure. For architects choosing or reviewing a structure.
- Researched
- 15 Oct 2026
- Reading time
- 5 min
- Sources
- 18
- Review due
- 15 Oct 2027
- They are not rivals: most of these styles answer different questions: how many deployables, how code is organised inside, how the core meets the outside, how variants are added.
- Start with deployment: a monolith unless parts truly need independent deployment or scaling; make it modular as soon as there are several areas or teams.
- Then decide per module: a Clean or hexagonal core where rules are complex, vertical slices where work is feature-by-feature CRUD.
- Ports at volatile edges, plug-ins for stable variability such as device families.
- Only some ratings are published: Mark Richards rates deployment-level styles; code-level ratings here are reasoned, and marked so.
On this page 7 sections
The contenders
| Style | Organises code by | In one line | Guide |
|---|---|---|---|
| Layered (N-tier) | Technical layer | UI → business → data, dependencies point down | — |
| Clean | Concentric rings, use cases at the centre | Dependencies point inward to business rules[8] | Field guide |
| Onion | Concentric rings, domain model at the centre | Clean’s close sibling with DDD vocabulary[10] | — |
| Hexagonal | Inside vs outside, joined by ports | The app is driven equally by UI, tests and scripts[7] | Field guide |
| Vertical Slice | Request or feature | Couple along the axis of change[11] | Field guide |
| Modular monolith | Business module | One deployable, enforced module boundaries[17] | Field guide |
| Plugin / Microkernel | Core plus extension points | Minimal core, independent plug-ins[6] | Field guide |
| Microservices | Business capability per process | Independent deployment at a network and operations premium[4] | — |
Microsoft’s .NET guide treats Hexagonal, Ports and Adapters, Onion and Clean as essentially one architecture under different names,[12] and Martin presented Clean as their unification.[8] Their columns below are close because they differ mainly in vocabulary and ceremony.
They are not rivals
Most confusion comes from comparing answers to different questions. Four decisions are largely independent:
Fowler makes the same point about layers: presentation, domain and data layering should not be the top-level split of a larger system; split by domain module first and layer inside each module.[5] Martin’s “screaming architecture” argues the same from the other side: the top-level structure should reveal the use cases, not the framework.[9]
Criteria
| Criterion | Question it answers |
|---|---|
| Change locality | How many places does a typical feature change touch? |
| Rule testability | Can business rules be tested without UI, database or devices? |
| Enforcement effort | How much discipline or tooling keeps the structure from decaying? |
| Team scaling | How many teams can work in parallel without colliding? |
| Extension without redeploy | Can a capability ship without a new build of the core? |
| Low ceremony | How little structure is needed on day one? |
Ratings
●●● strong · ●● medium · ● weak. For “enforcement effort” more dots mean less effort. Ratings marked R follow Mark Richards’ published star ratings;[1] all other cells are this article’s reasoning, because Richards rates deployment-level styles and does not rate code-level ones such as Clean, Hexagonal, Onion or Vertical Slice.
| Style | Change locality | Rule testability | Enforcement effort | Team scaling | Extension without redeploy | Low ceremony |
|---|---|---|---|---|---|---|
| Layered | ● (R) | ● | ●●● | ● | ● (R) | ●●● (R) |
| Clean | ●● | ●●● | ●● | ●● | ● | ● |
| Onion | ●● | ●●● | ●● | ●● | ● | ● |
| Hexagonal | ●● | ●●● | ●● | ●● | ●● | ●● |
| Vertical Slice | ●●● | ●● | ● | ●● | ● | ●●● |
| Modular monolith | ●● (R) | ●● | ● | ●●● | ● (R) | ●●● (R) |
| Plugin / Microkernel | ●●● for plug-in work (R) | ●●● | ●● | ●●● | ●●● (R) | ●● (R) |
| Microservices | ●●● within a service (R) | ●●● | ●●● in code, ● in operations | ●●● | ●●● (R) | ● (R) |
Two cells deserve a note. Layered designs make rule testing hard because the business layer depends on the data layer and often needs a test database.[12] Modular monoliths score low on enforcement effort because boundaries need tooling: Shopify built a dedicated checker and later found static checks only partly effective.[15][16]
Strengths and weaknesses in brief
| Style | Choose it for | Watch out for |
|---|---|---|
| Layered | Small, short-lived, forms-over-data tools | Every change ripples through every layer[13] |
| Clean / Onion | Long-lived systems whose value is in the rules | Ceremony; Palermo himself says it is not for small websites[10] |
| Hexagonal | Several inputs, volatile devices or data sources, testing without hardware | Adapter code without a second adapter is overhead |
| Vertical Slice | Feature-by-feature work, parallel development | Needs refactoring skill and mechanical guardrails[11] |
| Modular monolith | Several business areas or teams in one product | Boundaries decay without enforcement[14] |
| Plugin / Microkernel | Stable variability shipped independently, third-party extensions | Contract churn and isolation costs |
| Microservices | Independent deployment, scaling or technology per part | The microservice premium in operations and design[4] |
Scenarios
| Scenario | Recommendation | Why |
|---|---|---|
| Small CRUD admin tool | Layered, or a single-project vertical slice | Lowest ceremony; protected cores are overkill |
| Long-lived device configuration tool with many device families | Plug-in host with one plug-in per device family; a Clean or hexagonal core with device I/O behind ports; slices for UI features | Variants ship without core releases; simulators double as test adapters. If all families always ship together, a modular monolith with one module per family is simpler |
| Product configurator with complex rules | Clean or hexagonal core around the rules domain; slices for the surrounding CRUD | The rules need isolated tests and consistency; keep them in one place |
| Several teams on one product | Modular monolith with enforced boundaries | Team autonomy without the distributed-systems premium[14][4] |
| Startup or MVP | Monolith with simple layers or slices | Boundaries are not known yet and are cheap to move in-process[3] |
| Regulated or safety-relevant tool | Clean or hexagonal core inside a modular monolith; plug-ins only if each can be qualified and its contract versioned | An explicit dependency rule supports isolated verification and audit |
| Customer or partner extensibility | Plugin / microkernel with a stable, versioned API | Extension without redeploying the core[6] |
| Legacy N-tier you must keep | Invert the business-to-data dependency; grow new features as slices or modules | Improves testability without a rewrite[12] |
Decision procedure
- Do parts need independent deployment, scaling or release cadence? If not, build a monolith.[3] If yes, weigh the microservice premium honestly.[4]
- Are there several business areas or more than one team? Make it a modular monolith and decide now how boundaries will be enforced.
- Must variants ship without rebuilding the core? Use plug-ins, and design the contract first.
- For each module, are the rules complex or mostly CRUD? Complex: a Clean or hexagonal core. CRUD: slices or simple transaction scripts.
- Are there many devices, integrations or test drivers at the edges? Put ports and adapters there.
- Is the team ready? Slices depend on refactoring skill; Clean depends on mapping discipline.
- How long will it live? Long-lived: invest in boundaries early. Short-lived: pick the simplest option.
The Azure Architecture Center frames the same choice: each style trades agility, complexity and operational cost differently, and none is right for everything.[13] Richards’ lessons make the matching point that layered architecture is not obsolete and that a modular monolith is a natural starting point for later migration.[2]
Key takeaways
- Choose along four axes (deployment, code inside, edges, extension), not from one list of eight styles.
- Monolith first, modular early: boundaries are cheaper to learn and move in-process.
- Match the inside of each module to its work: rules get a protected core, CRUD gets slices.
- Use ports and adapters where technology varies and plug-ins where business variants must ship independently.
- Every structure decays without enforcement: references, architecture tests, verification tools.
Sources
- Architecture Styles Worksheet V2.0 · Mark Richards, star ratings per stylePrimarydevelopertoarchitect.com
- Software Architecture Monday, lesson 159 · Mark RichardsPrimarydevelopertoarchitect.com
- MonolithFirst · Martin Fowler, 2015Primarymartinfowler.com
- MicroservicePremium · Martin Fowler, 2015Primarymartinfowler.com
- PresentationDomainDataLayering · Martin Fowler, 2015Primarymartinfowler.com
- Plugin · Martin Fowler, Patterns of Enterprise Application ArchitectureReferencemartinfowler.com
- Hexagonal Architecture · Alistair Cockburn, 2005Primaryalistair.cockburn.us
- The Clean Architecture · Robert C. Martin, 2012Primaryblog.cleancoder.com
- Screaming Architecture · Robert C. Martin, 2011Primaryblog.cleancoder.com
- The Onion Architecture, part 1 · Jeffrey Palermo, 2008Primaryjeffreypalermo.com
- Vertical Slice Architecture · Jimmy Bogard, 2018Primaryjimmybogard.com
- Common web application architectures · Microsoft LearnPrimarylearn.microsoft.com
- Architecture styles · Azure Architecture CenterPrimarylearn.microsoft.com
- Modular monolith · Simon BrownPrimarysimonbrown.je
- Deconstructing the Monolith · Shopify Engineering, 2019Primaryshopify.engineering
- A Packwerk retrospective · Shopify Ruby team, 2024Primaryrailsatscale.com
- Modular Monolith: a primer · Kamil Grzybek, 2019Secondarykamilgrzybek.com
- Spring ModulithReferencespring.io