Clean Architecture in TypeScript

Sanjeev SharmaSanjeev Sharma
2 min read

Advertisement

Clean Architecture organizes code by layers. Each layer has clear responsibilities and dependencies flow inward.

Layers

src/
  domain/           # Business logic
    entities/
    usecases/
    repositories/
  infrastructure/   # Frameworks, DBs
    database/
    http/
  presentation/     # Controllers, routes
    controllers/
    routes/

Implementation

// Domain Entity
export interface User {
  id: number;
  email: string;
  name: string;
}

// Repository Interface
export interface UserRepository {
  save(user: User): Promise<User>;
  findById(id: number): Promise<User | null>;
  findByEmail(email: string): Promise<User | null>;
}

// Use Case
export class CreateUserUseCase {
  constructor(private userRepository: UserRepository) {}

  async execute(email: string, name: string): Promise<User> {
    const existing = await this.userRepository.findByEmail(email);
    if (existing) throw new Error("User exists");

    const user: User = { id: Math.random(), email, name };
    return this.userRepository.save(user);
  }
}

// Infrastructure Implementation
export class PostgresUserRepository implements UserRepository {
  async save(user: User): Promise<User> {
    // Database code
    return user;
  }

  async findById(id: number): Promise<User | null> {
    // Database code
    return null;
  }

  async findByEmail(email: string): Promise<User | null> {
    // Database code
    return null;
  }
}

// Presentation (Controller)
export class UserController {
  constructor(private createUserUseCase: CreateUserUseCase) {}

  async create(req: any, res: any) {
    const user = await this.createUserUseCase.execute(
      req.body.email,
      req.body.name
    );
    res.json(user);
  }
}

Benefits

  • Testable: Mock dependencies easily
  • Maintainable: Clear separation of concerns
  • Flexible: Swap implementations
  • Independent: Frameworks don't dictate structure

FAQ

Q: Is Clean Architecture overkill? A: For small projects, yes. For large teams and complex logic, essential.


Clean Architecture scales with your application.

Advertisement

Sanjeev Sharma

Written by

Sanjeev Sharma

Full Stack Engineer · E-mopro