Application Architecture MOC
Application Architecture MOC
Navigation hub for six application architecture patterns organised into two families. These patterns are the structural shells that organise individual design patterns — GoF, DDD, EIP — into cohesive system architectures. See Design-Patterns-MOC for the root vault entry point.
Layered Family
Patterns that organise code by technical concern. All three patterns share the same foundational principle — dependency inversion — but differ in vocabulary and the granularity at which they name their layers.
| Pattern | Intent | Use When |
|---|---|---|
| Clean-Architecture | Enforce strict dependency rule: nothing in an inner circle can know anything about an outer circle. Four rings: Entities, Use Cases, Interface Adapters, Frameworks & Drivers. | Team uses Robert C. Martin's vocabulary; need to enforce layer boundaries with tooling (ts-arch, ArchUnit) |
| Hexagonal-Architecture | Isolate application core from all external systems via ports (interfaces) and adapters (implementations). | Integrating with multiple external systems (DBs, APIs, queues); want test-seam architecture; Cockburn vocabulary |
| Onion-Architecture | Domain-centric layering: Domain Model and Domain Services at the centre; Application Services and Infrastructure on the outside. Dependencies flow inward only. | DDD-heavy codebase; team uses Palermo vocabulary; need to distinguish Domain Services from Application Services |
Layered family selection guide: All three patterns solve the same problem — preventing infrastructure from coupling to domain logic. Choose based on the vocabulary your team already uses. If you have no prior commitment, Clean-Architecture has the widest ecosystem documentation. If you already practice DDD with distinct Domain and Application Services, use Onion-Architecture. If you have multiple external systems and want to name your integration boundaries as ports, use Hexagonal-Architecture.
Family Relationships
The three layered family architectures share a common ancestor in the Dependency Inversion Principle. The table below makes their vocabulary differences concrete.
| Architecture | Layer Names | Dependency Rule Statement | Repository Interface Placement | Origin |
|---|---|---|---|---|
| Clean Architecture | Entities / Use Cases / Interface Adapters / Frameworks & Drivers | Nothing in an inner circle can know anything about something in an outer circle | Use Cases layer (interface), Frameworks & Drivers layer (implementation) | Robert C. Martin, 2012 |
| Hexagonal Architecture | Application Core (hexagon) / Ports / Adapters | All dependencies point inward toward the application core | Secondary port interface (inside hexagon), driven adapter (outside hexagon) | Alistair Cockburn, 2005 |
| Onion Architecture | Domain Model / Domain Services / Application Services / Infrastructure | Dependencies flow inward; outer rings depend on inner rings, never the reverse | Domain Services ring (interface), Infrastructure ring (implementation) | Jeffrey Palermo, 2008 |
Orthogonal Architectures
Patterns that organise code by feature, module, or team boundary rather than technical concern. These are orthogonal to the layered family: a Modular Monolith can use Clean Architecture internally, and a Vertical Slice can sit inside a Hexagonal core.
| Pattern | Intent | Use When |
|---|---|---|
| Vertical-Slice-Architecture | Organise code by feature slice end-to-end (handler, query, domain, UI). Each slice owns everything it needs — no cross-slice coupling at the handler level. | 5+ distinct use cases; teams step on each other's code in a layered codebase; want to ship features independently |
| Modular-Monolith | Deploy as a single unit but enforce strict module boundaries around each Bounded Context. Modules communicate only through defined public APIs. | Multiple Bounded Contexts with shared deployment cadence; not yet ready for microservices but need encapsulation |
| Micro-Frontends | Decompose a frontend into independently deployed applications composed at runtime (shell + remotes). | 3+ independent frontend teams with independent release cadences; each team owns a distinct business domain in the UI |
Orthogonal architectures selection guide: If your organisation has multiple frontend teams that cannot coordinate releases, Micro-Frontends is the threshold-based choice (3+ teams required). For backend systems with multiple Bounded Contexts in a single deployment, prefer Modular-Monolith over jumping to microservices. If teams are fighting over a layered backend codebase, introduce Vertical-Slice-Architecture to reduce cross-team coupling at the feature level.
Selection Guide
All Six Architectures — Comparison
| Architecture | Team Size | Codebase Complexity | Deployment Model | Best For |
|---|---|---|---|---|
| Clean-Architecture | Any | Medium to large | Single deployable or microservice | Codebases needing strict layer boundary enforcement with tooling; widest documentation ecosystem |
| Hexagonal-Architecture | Any | Medium to large | Single deployable or microservice | Systems integrating with multiple external adapters (DB, queue, API); test-seam architecture |
| Onion-Architecture | Any | Medium to large | Single deployable or microservice | DDD-heavy codebases where Domain Services and Application Services need explicit separation |
| Vertical-Slice-Architecture | Medium (5-15) | Medium to large | Single deployable | Feature-oriented teams; 5+ distinct use cases; reduce cross-team coupling in layered codebase |
| Modular-Monolith | Medium to large | Large | Single deployable | Multiple Bounded Contexts; shared deployment; stepping stone from monolith to microservices |
| Micro-Frontends | Large (3+ frontend teams) | Large | Multiple independently deployed frontends | Independent frontend teams with independent release cadences |
Note: Layered and orthogonal architectures are composable. A Modular-Monolith can use Clean-Architecture internally within each module. A Vertical-Slice-Architecture codebase can adopt Hexagonal-Architecture ports for its infrastructure boundaries. "Choose one" is rarely the correct answer.
Architecture Selection — Start Here
Is your system composed of multiple independently deployed frontend applications? -> Yes, with 3+ independent frontend teams: Micro-Frontends -> No: Continue
Is your system a single deployable unit with multiple Bounded Contexts? -> Yes: Modular-Monolith (modules can use layered or slice architecture internally) -> No, single Bounded Context: Continue
Does your team navigate code by feature or by technical layer? -> By feature (what user capability does this code serve?): Vertical-Slice-Architecture -> By technical layer (what technical concern does this code handle?): Continue
Which vocabulary does your codebase or team already use? -> "Ports and Adapters," "driving/driven ports," Cockburn: Hexagonal-Architecture -> "Domain Services vs Application Services," DDD-heavy, Palermo: Onion-Architecture -> "Entities, Use Cases," Robert C. Martin, Uncle Bob: Clean-Architecture -> None yet: Clean-Architecture (widest ecosystem documentation)
Sources
- Martin, Robert C. — Clean Architecture: A Craftsman's Guide to Software Structure and Design, Prentice Hall, 2017
- Cockburn, Alistair — "Hexagonal Architecture" (Ports and Adapters), alistair.cockburn.us, 2005
- Palermo, Jeffrey — "The Onion Architecture" (four-part blog series), jeffreypalermo.com, 2008
- Bogard, Jimmy — "Vertical Slice Architecture" (NDC Sydney talk and blog), 2018
- Newman, Sam — Building Microservices, 2nd ed., O'Reilly, 2021
- Jackson, Cam and Fowler, Martin — "Micro Frontends", martinfowler.com, 2019
Related MOCs
- Frontend-Architecture-MOC — Frontend Architecture extends the Micro-Frontends pattern with intra-application patterns: state management paradigm selection, rendering strategy selection, and component composition patterns. Where Application-Architecture-MOC covers the macro-level shell (how applications compose), Frontend-Architecture-MOC covers the micro-level internals (how components, state, and rendering are structured within a frontend application).