November 23, 2025 (10d ago)

robert c martin clean architecture: A Practical Guide

robert c martin clean architecture distilled: explore core principles with practical TypeScript examples and learn to build maintainable, scalable software.

← Back to blog
Cover Image for robert c martin clean architecture: A Practical Guide

robert c martin clean architecture distilled: explore core principles with practical TypeScript examples and learn to build maintainable, scalable software.

Robert C. Martin: Clean Architecture in TypeScript

robert c. martin clean architecture distilled: explore core principles with practical TypeScript examples and learn to build maintainable, scalable software.

Architectural sketch showing concentric circles within a house structure representing clean architecture layers and dependencies

Introduction

Clean Architecture is a design approach that keeps your core business logic separate from frameworks, databases, and the UI. It organises code into concentric layers with one simple rule: dependencies must always point inward. That separation makes systems easier to test, maintain, and adapt as technologies and teams change. This guide distills Robert C. Martin’s ideas into practical principles and a TypeScript implementation blueprint you can apply right away.1

What Is Clean Architecture?

Imagine building a house where you can replace the foundation or rewire the electrical system without tearing down walls. That’s the idea behind Clean Architecture. It’s a philosophy for designing software with clear separation of concerns so the most important parts—the business rules—remain pure and stable even when external details change.

This layered model helps you focus on the application’s purpose first and implementation details second. That mindset is the first step toward software that’s durable and easy to evolve.

The Foundational Dependency Rule

At the heart of Clean Architecture is the Dependency Rule: source code dependencies can only point inwards. Inner layers must not depend on outer layers. This creates a protective boundary around your business rules so they don’t become coupled to a specific database, framework, or UI.

By decoupling your software from technical details, you reduce the cost of change and future-proof your core logic. Developers can swap out tools without touching the rules that matter most.

Beyond a Simple Layered Model

Clean Architecture is not just another pattern. It’s a way to think about software structure for long-term projects. Industry research shows that teams adopting modern architecture and delivery practices achieve measurable improvements in performance and stability, including faster lead times and lower failure rates for changes.2

To contrast approaches, here are the key differences between Clean Architecture and a traditional monolith.

Clean Architecture vs Monolithic Architecture

AspectClean ArchitectureMonolithic Architecture
DependenciesControlled, point inward toward business logic.Tightly coupled components with direct knowledge of each other.
TestabilityHigh; core logic can be tested in isolation.Low; often requires full integration environment.
MaintainabilityEasier; changes rarely impact core logic.Harder; small changes can cascade.
Technology ChoicesFlexible; external tools act like plugins.Rigid; changes are costly.
FocusBusiness domain and rules.Often database or UI driven.

The Four Layers of Clean Architecture

Robert C. Martin’s model uses four concentric layers. The innermost layer contains the domain’s core, shielded from external details. All arrows point inward—dependencies flow from outer layers to inner ones.

Concentric circles diagram illustrating clean architecture layers from core entities to outer frameworks and adapters

Layer 1: Entities

Entities are the pure business objects. They encapsulate fundamental business rules and data structures. For example, an Order entity might implement addItem() which checks inventory and recalculates totals. Entities don’t know how they’re stored or presented.

Layer 2: Use Cases

Use Cases (or Interactors) implement application-specific business rules. They orchestrate Entities and repositories to achieve a purpose, like PlaceOrder. Use Cases express the intent of the application and remain independent of UI and database implementations.

Layer 3: Interface Adapters

Interface Adapters translate data between the inner layers and external systems. Typical components include:

  • Presenters and Views: format data for display.
  • Controllers: accept input from the UI and call Use Cases.
  • Gateways/Repositories: abstract persistence with interfaces the Use Cases depend on.

Adapters decouple core logic from frameworks by converting framework-specific types into plain data objects.

Layer 4: Frameworks and Drivers

The outer layer contains frameworks, databases, UI libraries, and other external tools. These are implementation details that should never be referenced by the inner layers. Because they sit on the outside, they can be swapped with minimal impact on the core.

Why Clean Architecture Matters

Adopting Clean Architecture is a strategic move that reduces long-term risk and cost. It improves testability, maintainability, and the ability to adopt new technologies without invasive rewrites. Teams that embrace well-structured architecture and modern delivery practices often see measurable gains in deployment speed and software reliability.2

Testability and Maintainability

When your core business logic is independent of external frameworks, you can write fast, reliable unit tests that don’t require databases or full UI stacks. Better testability leads to better maintainability. Organizations using solid architecture and testing practices typically increase automated test coverage and reduce time to fix bugs, which lowers maintenance costs over time.

Future-Proofing

Clean Architecture treats frameworks and services as replaceable plugins. If a database becomes too costly or a front-end framework falls out of favor, you can swap the outer layers and keep the inner rules intact. This flexibility makes it easier to integrate new capabilities, like AI models, without wholesale rewrites.

A TypeScript Implementation Blueprint

Theory is useful, but code shows how principles map to practice. Here’s a practical folder layout for a TypeScript + Next.js application that enforces the Dependency Rule by design.

Hand-drawn diagram showing clean architecture layers with entities, use cases, and framework components connected by arrows

Make directories mirror layers so dependencies are obvious from the folder tree. This structure helps new developers get productive fast.

Core Domain Layer

  • /domain/entities — business objects like Order.ts with methods such as addItem().
  • /domain/repositories — interfaces like IOrderRepository.ts with findById(id: string) and save(order: Order).
  • /domain/use-cases — orchestrators like CreateOrder.ts.

This layer is framework-agnostic and fully testable in isolation.

Infrastructure Layer

  • /infrastructure/repositories — concrete implementations, for example PrismaOrderRepository.ts.
  • /infrastructure/services — integrations like StripePaymentGateway.ts or SendGridEmailService.ts.

Swap implementations without touching the domain by adhering to repository interfaces.

Presentation Layer

In Next.js, this maps to the app directory:

  • /app/api/orders/route.ts — Controller that calls Use Cases and uses a Presenter for responses.
  • /app/orders/[id]/page.tsx — View component that renders UI and delegates complex logic to hooks.

Keeping components thin and delegating logic improves readability and testability.

Sample Folder Structure (Next.js)

DirectoryResponsibilityExample Files
src/appPresentation Layer: UI and API routes.page.tsx, layout.tsx, api/orders/route.ts
src/domainCore business logic.entities/User.ts, use-cases/CreateUser.ts
src/domain/entitiesBusiness objects.Order.ts, Product.ts
src/domain/repositoriesAbstract data contracts.IOrderRepository.ts, IUserRepository.ts
src/domain/use-casesApplication rules.CreateOrder.ts, GetUserProfile.ts
src/infrastructureImplementations and services.repositories/PrismaOrderRepository.ts, services/Stripe.ts
src/libUtilities and types.utils.ts, constants.ts

This is a flexible starting point you can adapt as the project grows.

Common Anti-Patterns and Pitfalls

Using Clean Architecture poorly can create needless complexity. Here are frequent mistakes to avoid.

Anemic Domain Model

An anemic domain model turns Entities into mere data bags while moving business logic into bloated service classes. A healthy domain keeps logic inside Entities so they enforce their own rules.

Leaky Abstractions

If core logic imports framework types or database drivers, boundaries are leaking. Avoid passing framework-specific objects like NextApiRequest into Use Cases. Use Adapters to convert external inputs into plain data objects.

Dogmatic Over-Engineering

Apply Clean Architecture pragmatically. For small or short-lived projects, a lighter approach can be more efficient. Start with separation between business logic and framework code, then introduce more formal layers as complexity increases.

Refactoring a Legacy App

You can migrate a legacy app gradually. Avoid big-bang rewrites. Use the Strangler Fig Pattern: replace one feature at a time with a clean implementation and reroute traffic once it’s ready. Repeat until the legacy code is replaced.3


At Clean Code Guy, we help teams audit and refactor codebases, run workshops, and deliver practical guidance so projects stay maintainable. Find out how we can help at https://cleancodeguy.com.

Frequently Asked Questions

Q: Is Clean Architecture overkill for small projects?

A: For quick prototypes, strict layering can add unnecessary overhead. If a project may grow or be maintained long-term, a “clean-ish” separation between business logic and framework code offers big future savings.

Q: How does Clean Architecture differ from Hexagonal or Onion Architecture?

A: They’re variations on the same idea. All aim to protect the core business logic by making dependencies point inward. The differences are mainly terminology and mental models.

Q: Can I migrate a legacy system to Clean Architecture without a full rewrite?

A: Yes. Use the Strangler Fig Pattern to incrementally replace components. Build new features with clean boundaries and gradually redirect traffic from the old system to the new one.3

1.
Robert C. Martin, Clean Architecture: A Craftsman’s Guide to Software Structure and Design (Prentice Hall, 2017). [https://www.oreilly.com/library/view/clean-architecture/9780134494272]
2.
Google Cloud, Accelerate State of DevOps Report (2023). [https://cloud.google.com/devops/state-of-devops]
3.
Martin Fowler, “Strangler Fig Application.” [https://martinfowler.com/bliki/StranglerApplication.html]
← Back to blog
🙋🏻‍♂️

AI writes code.
You make it last.

In the age of AI acceleration, clean code isn’t just good practice — it’s the difference between systems that scale and codebases that collapse under their own weight.