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.

PatternIntentUse When
Clean-ArchitectureEnforce 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-ArchitectureIsolate 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-ArchitectureDomain-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.

ArchitectureLayer NamesDependency Rule StatementRepository Interface PlacementOrigin
Clean ArchitectureEntities / Use Cases / Interface Adapters / Frameworks & DriversNothing in an inner circle can know anything about something in an outer circleUse Cases layer (interface), Frameworks & Drivers layer (implementation)Robert C. Martin, 2012
Hexagonal ArchitectureApplication Core (hexagon) / Ports / AdaptersAll dependencies point inward toward the application coreSecondary port interface (inside hexagon), driven adapter (outside hexagon)Alistair Cockburn, 2005
Onion ArchitectureDomain Model / Domain Services / Application Services / InfrastructureDependencies flow inward; outer rings depend on inner rings, never the reverseDomain 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.

PatternIntentUse When
Vertical-Slice-ArchitectureOrganise 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-MonolithDeploy 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-FrontendsDecompose 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

ArchitectureTeam SizeCodebase ComplexityDeployment ModelBest For
Clean-ArchitectureAnyMedium to largeSingle deployable or microserviceCodebases needing strict layer boundary enforcement with tooling; widest documentation ecosystem
Hexagonal-ArchitectureAnyMedium to largeSingle deployable or microserviceSystems integrating with multiple external adapters (DB, queue, API); test-seam architecture
Onion-ArchitectureAnyMedium to largeSingle deployable or microserviceDDD-heavy codebases where Domain Services and Application Services need explicit separation
Vertical-Slice-ArchitectureMedium (5-15)Medium to largeSingle deployableFeature-oriented teams; 5+ distinct use cases; reduce cross-team coupling in layered codebase
Modular-MonolithMedium to largeLargeSingle deployableMultiple Bounded Contexts; shared deployment; stepping stone from monolith to microservices
Micro-FrontendsLarge (3+ frontend teams)LargeMultiple independently deployed frontendsIndependent 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
  • 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).