Skip to main content

ADR-001: Turborepo Monorepo Structure

Date: 2024-01-01

Status: Accepted

Context

The Chompardo platform consists of multiple applications (frontend, backend services) and shared code (UI components, configurations). We needed to decide how to organize the codebase:

  1. Polyrepo - Separate repositories for each package
  2. Monorepo - Single repository containing all packages

Key considerations:

  • Multiple developers working across frontend and backend
  • Shared UI components and configurations
  • Need for atomic changes across packages
  • CI/CD complexity
  • Code sharing and reuse

Decision

We will use a Turborepo monorepo structure with pnpm workspaces.

The repository is organized into three main directories:

  • apps/ - Deployable applications
  • packages/ - Shared libraries and configurations
  • services/ - Backend services
monorepo/
├── apps/
│ └── signin/
├── packages/
│ ├── ui/
│ ├── eslint-config/
│ └── typescript-config/
├── services/
│ └── identity/
└── turbo.json

Consequences

Positive

  • Atomic changes - Can update shared code and consumers in a single PR
  • Consistent tooling - Shared ESLint, TypeScript, and Prettier configs
  • Efficient caching - Turborepo caches build outputs, speeding up CI
  • Simplified dependency management - pnpm workspaces handle internal dependencies
  • Better code discoverability - All code in one place

Negative

  • Larger repository size - All code in one repo means larger clones
  • Learning curve - Developers need to understand Turborepo and workspaces
  • CI complexity - Need to configure proper filtering to avoid unnecessary builds
  • Potential for tight coupling - Easier to create unwanted dependencies

Alternatives Considered

1. Polyrepo with npm packages

Separate repositories publishing to a private npm registry.

Rejected because:

  • Slower iteration when changing shared code
  • Complex versioning across packages
  • Higher maintenance overhead for CI/CD per repo

2. Nx monorepo

Using Nx instead of Turborepo.

Rejected because:

  • Turborepo has simpler configuration
  • Better integration with Vercel (same company)
  • Sufficient features for our scale
  • Nx's additional features (generators, plugins) not needed initially

3. Lerna monorepo

Using Lerna for monorepo management.

Rejected because:

  • Lerna is now maintained by Nx team and recommends Nx
  • Turborepo has better caching and performance
  • More active development and community