Categories: softare development

React Clean Architecture

React Clean Architecture applies the principles of Clean Architecture (introduced by Robert C. Martin, “Uncle Bob”) to frontend development. The goal is to build applications that are scalable, testable, maintainable, and easy to extend—even as your project grows large.

Why Clean Architecture in React?

As React apps grow, they often become messy:

  • Components handle business logic.
  • API calls are scattered everywhere.
  • UI and logic tightly coupled.
  • Hard to test or reuse code.

Clean Architecture solves these by enforcing separation of concerns and layered boundaries.

Learn React Online

Core Principles

  1. Dependency Inversion
    Inner layers must not depend on outer layers.
    Example: business rules should not depend on React components.
  2. Separation of Concerns
    Each layer has a single purpose (UI, logic, data).
  3. Testability
    With isolated layers, unit tests become easier.
  4. Maintainability
    New features can be added without breaking unrelated areas.

React Clean Architecture Layers

Clean Architecture divides the app into four major layers:

1. Presentation Layer (React Components)

This is where your pages, components, routes, and UI live.

Responsibilities:

  • Display data to users.
  • Collect user input.
  • Call use cases (business rules).
  • No business or API logic.

Example:

function LoginPage({ login }) {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");

  const handleSubmit = () => login({ email, password });

  return (
    <div>
      <input onChange={e => setEmail(e.target.value)} />
      <input type="password" onChange={e => setPassword(e.target.value)} />
      <button onClick={handleSubmit}>Login</button>
    </div>
  );
}

2. Domain Layer (Business Rules)

This is the heart of your app.
It contains entities, business logic, interfaces, and use cases.

What lives here?

  • Entities (core models)
  • Use cases / services
  • Pure business logic
  • Validations
  • Interfaces (contracts)

Example Use Case:

export function loginUserUseCase(authRepository) {
  return async (credentials) => {
    if (!credentials.email || !credentials.password) {
      throw new Error("Missing fields");
    }
    return authRepository.login(credentials);
  };
}

Domain layer has no knowledge of HTTP, UI, or databases.

3. Data Layer (APIs, DBs, External Services)

Implements the interfaces defined in the domain layer.

Responsibilities:

  • Calling APIs
  • Implementing repositories
  • Handling local storage
  • Mapping responses to domain entities

Repository Example:

export class AuthRepositoryImpl {
  constructor(apiClient) {
    this.apiClient = apiClient;
  }

  async login(credentials) {
    const response = await this.apiClient.post("/login", credentials);
    return response.data;
  }
}

4. Infrastructure Layer

Everything framework-specific or technical details:

Examples:

  • Axios instance
  • Firebase config
  • Local storage utilities
  • Logging tools

Example:

import axios from "axios";

export const apiClient = axios.create({
  baseURL: "https://api.example.com",
});

How the Layers Talk to Each Other

UI (React)
   ↓
Use Cases (Domain)
   ↓
Repositories (Data)
   ↓
API/Database (Infrastructure)

But not in reverse.

The domain layer never imports React, never imports Axios, and never imports APIs.

Folder Structure Example

A recommended project structure:

src/
 ├─ presentation/          # UI: components, pages, hooks
 │   ├─ components/
 │   ├─ pages/
 │   └─ routes/
 │
 ├─ domain/                # business logic
 │   ├─ entities/
 │   ├─ usecases/
 │   └─ repositories/
 │
 ├─ data/                  # API + repository implementations
 │   ├─ repositories/
 │   └─ mappers/
 │
 ├─ infrastructure/        # Framework-specific implementations
 │   └─ http/
 │
 └─ app/                   # DI container, providers
     └─ container.js

Dependency Injection (DI)

In React Clean Architecture, DI is used to assemble dependencies.

Example Container:

import { apiClient } from "../infrastructure/http/apiClient";
import { AuthRepositoryImpl } from "../data/repositories/AuthRepositoryImpl";
import { loginUserUseCase } from "../domain/usecases/loginUserUseCase";

const authRepository = new AuthRepositoryImpl(apiClient);

export const loginUser = loginUserUseCase(authRepository);

Then pass use cases to components.

Benefits of Using Clean Architecture in React

Scalability

Large apps remain organized.

Reusability

Business rules can be reused across different UIs (React Native, Next.js, etc).

Testing

Domain and data logic are easy to unit test because they are pure.

Flexibility

Swap APIs, change UI, or change data sources without breaking the core logic.

Team Collaboration

Backend, frontend, and mobile teams can align on use cases and entities.

Real-World Example

For a login flow:

  • UI: only takes email + password and calls loginUser.
  • Domain: validates credentials and defines the login use case.
  • Data: communicates with /login endpoint.
  • Infrastructure: Axios handles HTTP.

Result: clean, decoupled, replaceable logic.

Conclusion

React Clean Architecture is not a strict rulebook—it’s a systematic way of organizing your app so it remains:

  • Clean
  • Scalable
  • Replaceable
  • Testable
  • Future-proof

Whether you’re building a small app or a production-level system, Clean Architecture gives your code clarity and purpose.

If you want, I can also create:

Recent Posts

Introduction to Phaser JS

Phaser JS is a powerful, open-source HTML5 game development framework used for creating 2D games that…

3 days ago

Web Authentication Libraries

JavaScript / Node.js Authentication Libraries 1. Passport.js One of the most popular authentication middleware libraries…

3 days ago

The Things They Carry: Software Developers Starter Packs

Every profession comes with its own set of tools. A carpenter has a toolbox, a…

3 days ago

CRUD Operations: The Foundation of Data Management

Every application that stores and manages data relies on a set of basic operations known…

2 weeks ago

Common PHP Mistakes Every Developer Should Avoid

PHP remains one of the most widely used server-side programming languages, powering platforms such as…

2 weeks ago

Danfo.js: The JavaScript Data Science Library

Danfo.js is an open-source JavaScript library designed for data manipulation, analysis, and machine learning. It provides…

2 weeks ago