A React + TypeScript application that explores the Clean Architecture approach for front‑end apps. It consumes the public GitHub APIs and showcases modular design, dependency inversion, and testability through a clean, layered structure.
- About the Project
- Features
- Architecture
- Tech Stack
- Project Structure
- Getting Started
- Contributing
- Roadmap
- Acknowledgements
- Contact
This repository demonstrates how to build a React application using Clean Architecture and design patterns that favor modularity, separation of concerns, and easy maintainability.
It integrates with the GitHub REST APIs to present real data while keeping the core rules of the app isolated from frameworks and external details.
- Clean, layered architecture with a clear separation of concerns
- Factory-based Dependency Injection for easy swapping of implementations
- Strong typing (TypeScript) and unit tests (Jest)
- Simple, real-world integration with GitHub APIs
- Scalable project structure designed for growth
The goal is to keep the business rules independent of frameworks and UI details. External concerns—such as HTTP clients or storage—live at the boundaries and can be replaced without touching the core.
+--------------------+
| Presentation | ← React components, hooks, view-models
+----------+---------+
|
v
+----------+---------+
| Application | ← orchestrates use cases, input/output ports
+----------+---------+
|
v
+----------+---------+
| Domain | ← entities, business rules, pure logic
+----------+---------+
|
v
+----------+---------+
| Data/Infra | ← implementations (GitHub API, storage, http)
+--------------------+
- Domain: Entities and business logic.
- Application (EntryPoint/Main): Use cases and input/output ports. In this project, the “Main” layer wires everything together.
- Data: Concrete repositories and mappers (e.g., GitHub API repositories).
- Infra: External details (HTTP client, persistence, framework integrations).
- Presentation: UI (React), containers, and adapters.
The Factory Pattern is used to wire dependencies without coupling the Presentation layer to concrete implementations.
// Domain
export interface UserRepository {
getUserById(id: string): Promise<User>;
}
// Data
export class UserDataRepository implements UserRepository {
async getUserById(id: string): Promise<User> {
// Fetch from GitHub API (or any source)
// map/validate into Domain entity
return { /* ... */ } as User;
}
}
// Main / factories
export const makeUserRepository = (): UserRepository => new UserDataRepository();
// Presentation
const UserRepoProvider: React.FC = () => {
return <UserRepo repo={makeUserRepository()} />;
};For more reading: Clean Architecture overview by Mehdi Hadeli
https://github.com/mehdihadeli/awesome-software-architecture/blob/main/docs/clean-architecture.md
- React 18+ (UI)
- TypeScript 5+ (type safety)
- Jest (unit tests)
- Node.js 18+ (tooling)
- Optional: ESLint and Prettier for code quality/formatting
A suggested structure that follows Clean Architecture principles:
src/
├─ domain/ # Core entities & business rules
│ ├─ entities/
│ ├─ value-objects/
│ └─ services/
├─ application/ # Use cases, ports (interfaces) and orchestrators
│ ├─ ports/
│ └─ usecases/
├─ data/ # Concrete repositories, mappers
│ ├─ repositories/
│ └─ mappers/
├─ infra/ # External concerns (http, storage, frameworks)
│ ├─ http/
│ └─ config/
├─ presentation/ # React UI, components, pages, hooks
│ ├─ components/
│ ├─ pages/
│ └─ hooks/
└─ main/ # Composition root (factories, providers)
└─ factories/
- Node.js 18+
- npm (or your preferred package manager)
npm install npm@latest -g# Clone
git clone https://github.com/MarcoRhayden/github-clean-arch-react
cd github-clean-arch-react
# Install deps
npm installnpm startYour app should be available at the URL printed by your dev server.
# Run unit tests
npm test
# Coverage
npm test -- --coverage