# React Clean Architecture

> Clean Architecture for React Web with TypeScript and Vite. Enforces strict separation between Core (domain), Infrastructure (adapters), and UI layers. Use when user says "create a feature", "refactor this module", "review architecture", "add a use case", or asks about ports/adapters, Result pattern, viewModels, or dependency injection in React. Do NOT use for React Native, backend code, or simple UI-only components without business logic.

- Skill: `bikach/react-clean-architecture` (Agent Skill, multi-file: 8 files)
- Install (CLI): `npx skillmds@latest add bikach/react-clean-architecture`
- Raw SKILL.md: https://api.skillmd.com/api/skills/bikach/react-clean-architecture/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: Bikach (https://skillmd.com/u/bikach)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/bikach/react-clean-architecture

---


# React Clean Architecture

Prescriptive architecture for React Web applications with TypeScript and Vite.

**Stack:** React 19 - TypeScript - Vite - Zustand (client state) - React Query (server state) - React Router

**Patterns:** Ports/Adapters - Use Cases - Result Pattern - ViewModel - Atomic Design

## Core Principle

**Core depends on NOTHING.** UI and Infrastructure can import from Core, never the other way around.

```
UI ──────────────┐
                 ├──▶ Core (entities, use cases, ports)
Infrastructure ──┘
```

## Project Structure

```
src/
├── ui/                              # Global components and hooks
│   ├── components/                  # Atomic Design
│   │   ├── atoms/                   # e.g., Button, Text, Icon
│   │   ├── molecules/               # e.g., InputField, Card
│   │   ├── organisms/               # e.g., Header, Form
│   │   └── templates/               # e.g., PageLayout
│   ├── hooks/                       # Global hooks (useToggle, useDebounce)
│   └── theme/                       # CSS variables, Tailwind config
│
├── modules/
│   ├── [bounded-context]/           # e.g., authentication, labs, licenses
│   │   ├── core/                    # Pure domain (no external dependencies)
│   │   │   ├── entities/            # Business types/interfaces
│   │   │   ├── ports/               # Interfaces (contracts)
│   │   │   └── usecases/            # Business logic
│   │   ├── infrastructure/          # Port implementations
│   │   │   └── adapters/
│   │   └── ui/                      # React-specific for this context
│   │       ├── components/
│   │       ├── pages/
│   │       ├── hooks/
│   │       ├── stores/              # Zustand stores
│   │       └── viewModels/          # UI orchestration
│   ├── shared/                      # Shared code between bounded contexts
│   └── app/                         # Application configuration
│       ├── dependencies/
│       ├── react/
│       ├── router/
│       └── main.tsx
│
├── types/                           # General types (ISO8601, Result)
└── utils/                           # Utility functions
```

## File Naming Conventions

| Type                 | Extension        | Example                     |
| -------------------- | ---------------- | --------------------------- |
| Entity               | `.entity.ts`     | `User.entity.ts`            |
| Port                 | `.port.ts`       | `AuthRepository.port.ts`    |
| Use Case             | `.usecase.ts`    | `Login.usecase.ts`          |
| Adapter              | `.adapter.ts`    | `AuthApi.adapter.ts`        |
| ViewModel            | `.viewModel.tsx` | `useLogin.viewModel.tsx`    |
| Store                | `.store.ts`      | `auth.store.ts`             |
| Model (API response) | `.model.ts`      | `LoginResponse.model.ts`    |
| Query hook           | `.query.ts`      | `useUser.query.ts`          |
| Mutation hook        | `.mutation.ts`   | `useCreateUser.mutation.ts` |

React components: `PascalCase.tsx` (e.g., `LoginPage.tsx`, `AuthenticationCard.tsx`)

## Layer Rules

### Core (`/modules/[context]/core/`)

Core is **pure and unaware of the outside world**.

```
Allowed:
  - Defines entities (types/interfaces)
  - Defines ports (dependency interfaces)
  - Contains use cases (business logic)
  - Uses Result pattern for errors
  - Can import from: types/, utils/, other files in the same core

Forbidden:
  - NEVER import from infrastructure/
  - NEVER import from ui/
  - NEVER depend on React
  - NEVER call APIs directly
```

### Infrastructure (`/modules/[context]/infrastructure/`)

Implements ports defined in Core.

```
Allowed:
  - Adapters implement ports
  - Handles API calls, storage, external services
  - Transforms external data to Core entities
  - Returns Result<T, E>
  - Can import from: core/ (ports, entities)

Forbidden:
  - NEVER contains business logic (just transformation/mapping)
  - NEVER import from ui/
```

### UI (`/modules/[context]/ui/`)

Everything React-specific for the bounded context.

```
Allowed:
  - Pages, components, hooks specific to the context
  - ViewModels orchestrate: use cases and stores
  - Zustand stores for client state
  - Can import from: core/ (entities, use cases, ports)
  - Can call an adapter directly for simple CRUD (via React Query)

Forbidden:
  - NEVER business logic in components
  - NEVER business logic in viewModels (delegate to use cases)
```

**When to use a Use Case vs direct Adapter?**

| Situation                                 | Approach                     |
| ----------------------------------------- | ---------------------------- |
| Simple fetch, basic CRUD                  | Direct adapter + React Query |
| Business logic, validation, orchestration | Use Case                     |

## Key Patterns

- **Result Pattern**: Explicit success/error handling without exceptions. See [references/result-pattern.md](references/result-pattern.md)
- **React Query**: Server state management with query keys factory, hooks, and cache invalidation. See [references/react-query-patterns.md](references/react-query-patterns.md)
- **Dependency Injection**: React Context-based DI with environment-specific implementations. See [references/dependency-injection.md](references/dependency-injection.md)

## Workflows

### Creating a New Feature

Follow the 9-step process: Entities → Port → Use Case → Adapter → Register dependency → Query Keys → Mutation Hook → ViewModel → Page.

Full walkthrough with code examples: [references/feature-workflow.md](references/feature-workflow.md)

### Refactoring Existing Code

Identify violations (business logic in components, direct API calls, inline types, hardcoded dependencies) and extract to the proper layer.

Process and examples: [references/refactoring-guide.md](references/refactoring-guide.md)

### Code Review

See [references/code-review-checklist.md](references/code-review-checklist.md) for the complete checklist.

## References

- [references/result-pattern.md](references/result-pattern.md) — Result type, use case usage, viewModel usage
- [references/react-query-patterns.md](references/react-query-patterns.md) — Query keys, hooks, mutations, conventions
- [references/dependency-injection.md](references/dependency-injection.md) — DI structure, providers, environment config
- [references/feature-workflow.md](references/feature-workflow.md) — Full 9-step feature creation walkthrough
- [references/refactoring-guide.md](references/refactoring-guide.md) — Violation identification, before/after examples
- [references/file-templates.md](references/file-templates.md) — Complete templates for each file type
- [references/code-review-checklist.md](references/code-review-checklist.md) — Code review checklist

