dev-tools

Monorepo

A monorepo is a source-control strategy where multiple, distinct-but-related projects — a frontend app, a backend API, a shared component library, internal tooling — live together in a single Git repository, rather than each being split into its own separate repo (a "polyrepo" or "multirepo" strategy). Companies like Google, Meta, and Vercel run famously large monorepos; in the SaaS/startup world, a common pattern is a monorepo containing a Next.js frontend, a backend API, and a shared `packages/` directory of code used by both (types, UI components, utility functions). Why it matters for AI/SaaS builders: a monorepo makes cross-project changes atomic — if you change a shared API type, you update the frontend and backend that depend on it in the same commit, and CI can validate the whole change together, rather than coordinating a change across two separate repos with separate PRs and version bumps. It also makes code sharing trivial (no need to publish an internal package to a private registry just to share a utility function between two apps) and gives a single source of truth for the whole codebase, which is particularly useful for AI coding agents — an agent with monorepo access can see and correctly update both sides of a full-stack change in one pass, instead of needing separate context and separate sessions for the frontend and backend repos. The trade-off is tooling complexity: a naive monorepo setup runs the full test suite and full build for every change regardless of what actually changed, which gets slow at scale, so monorepos typically need dedicated build orchestration tools. How it works: monorepo tooling like Turborepo, Nx, or Bazel adds two key capabilities on top of a plain multi-package repo — dependency-graph-aware task running (only rebuild/retest the packages actually affected by a given change, plus anything that depends on them) and remote caching (if another developer or CI already built a given package at this exact commit, reuse that build output instead of redoing the work). Worked example: a team's monorepo has `apps/web`, `apps/api`, and `packages/ui` (shared React components) and `packages/types` (shared TypeScript types). A developer changes a shared `Invoice` type in `packages/types` to add a new `taxAmount` field. Running `turbo run build` walks the dependency graph, sees that `packages/types` changed, and automatically rebuilds and retests not just that package but everything downstream that imports it — `apps/api` (which now needs to populate `taxAmount`) and `apps/web` (which needs to display it) — while skipping `packages/ui`, which doesn't depend on the changed type at all, saving significant CI time versus rebuilding the entire repo on every change.

Related terms

More Dev Tools terms