Monorepo architecture uses a single repository for multiple packages and applications, leveraging tools like Turborepo, Nx, and pnpm workspaces to manage shared dependencies, coordinated builds, and consistent tooling across projects.
pnpm, Yarn, and npm workspaces let local packages reference each other via workspace protocols without publishing to a registry, enabling atomic cross-package changes.
Turborepo and Nx analyze the dependency graph to run tasks in topological order, skipping unchanged packages and caching outputs for dramatic CI speed improvements.
Build outputs are cached by input hash and shared across developers and CI, so identical work is never repeated — Turborepo can reduce CI times by 40-80%.
A monorepo is a repository strategy containing independent packages with clear boundaries; a monolith is a tightly coupled single application. They are fundamentally different concepts.
A monorepo is a single repository containing multiple distinct projects, packages, or applications that may or may not be related. This is in contrast to polyrepo architecture, where each project lives in its own repository. Companies like Google, Meta, and Microsoft use monorepos at massive scale, and the JavaScript ecosystem has embraced this pattern for managing complex frontend applications and shared libraries.
The primary benefits are code sharing, atomic changes, and unified tooling. In a polyrepo setup, sharing code between projects requires publishing packages to a registry, managing versions, and coordinating updates across repositories. In a monorepo, packages import from each other directly using workspace protocols (workspace:*), and a single pull request can update a shared library and all its consumers simultaneously. This eliminates version drift and "dependency hell" that plague polyrepo setups.
pnpm workspaces, Yarn workspaces, and npm workspaces all provide the foundational capability: linking local packages together so they can reference each other without publishing. pnpm is particularly well-suited for monorepos because its content-addressable storage and strict dependency isolation prevent phantom dependencies (packages accidentally available because a sibling installed them). The pnpm-workspace.yaml file defines which directories contain packages.
Turborepo solves the key challenge of monorepo builds: dependency-aware task scheduling. It reads the dependency graph from your workspace configuration and runs tasks in the correct topological order. If package B depends on package A, Turborepo ensures A builds before B. It also provides remote caching — if a teammate already built a package with identical inputs, Turborepo downloads the cached output instead of rebuilding. This can reduce CI times by 40-80% in practice.
Nx offers similar build orchestration with additional features like affected-command analysis (only running tasks on packages changed since the last commit), computation caching, and a rich plugin ecosystem for specific frameworks. Nx tends to be more opinionated and feature-rich, while Turborepo focuses on being lightweight and easy to adopt incrementally.
A well-organized monorepo separates deployable applications (apps/) from reusable libraries (packages/). Shared configurations (TypeScript, ESLint, Prettier) live in dedicated packages and are extended by consumers. This structure enforces clear boundaries: a UI component library does not depend on a specific application, making it reusable across all apps.
Interviewers often ask about tradeoffs. Monorepos can suffer from slow CI without proper caching, complex tooling setup, and repository size growth. They also ask about dependency management — how workspace protocols work, how you ensure packages use compatible versions of shared dependencies, and how you handle publishing individual packages from a monorepo to npm.
A monorepo is not a monolith. A monolith is a single application with tightly coupled components. A monorepo is a repository strategy that can contain many independent, well-bounded packages. The packages can be deployed independently and have their own release cycles.
Fun Fact
Google's monorepo contains over 2 billion lines of code across 86 terabytes and is accessed by 25,000+ developers daily. They built a custom version control system called Piper because Git cannot handle a repository that large.