Architecture
Monorepo Structure
Understanding the Turborepo structure and flexibility.
We use Turborepo to manage our monorepo. This structure allows us to host multiple applications and shared packages in a single Git repository, facilitating code sharing and atomic commits.
Directory Structure
.
├── apps/
│ ├── accounts/ # Angular application for user management
│ ├── api/ # NestJS backend application
│ └── docs/general/ # Documentation site (React/Vite)
├── packages/
│ ├── eslint-config/ # Shared ESLint configurations
│ ├── shared/ # Shared types, DTOs, and utilities
│ ├── typescript-config/ # Shared TSConfigs
│ └── ui/ # Shared UI component library
├── package.json # Root configuration and scripts
└── turbo.json # Turborepo pipeline configurationKey Benefits
- Shared Code: The
packages/shareddirectory allows us to define TypeScript interfaces (DTOs, Entities) once and consume them in both the API and Frontend applications. This guarantees that the frontend is always in sync with the backend data structures. - Unified Tooling: We use a single lockfile (
pnpm-lock.yaml) and consistent configurations for ESLint, Prettier, and TypeScript across all projects. - Caching: Turborepo caches build outputs. If you haven't changed a package, Turbo won't rebuild it, significantly speeding up CI/CD pipelines.
- Dependency Management:
pnpmworkspaces allow us to link packages locally. Changes inpackages/uiare instantly reflected inapps/docswithout needing a publish/install cycle.
Workspaces
This project is configured as a pnpm workspace. The pnpm-workspace.yaml file defines the locations of the workspace packages:
packages:
- 'apps/*'
- 'packages/*'