Guide

A monorepo keeps many packages in one repository. That is convenient until every commit rebuilds and retests everything. The fix is affected-target builds: compute which packages a change touches, then run only those and the packages that depend on them.

Concept

A dependency graph records which package imports which. Its reverse dependents are the packages that import a changed package, directly or indirectly. Those are the ones that can break.

Walking through a change

Here is a small graph. An arrow means "imports".

Suppose a change touches packages/auth. Then auth must rebuild, and so must everything that imports it: api and web. billing does not import auth, so its build and tests can be skipped and stay green. If the change touches only billing, then only billing runs.

Tools such as Bazel, Nx, Turborepo and Pants compute this graph for you. Each one also runs the affected targets, often in parallel.

A remote build cache shares the results across machines. The second engineer to build the same commit reuses the first engineer's artifacts, and pays almost nothing.

Monorepo or many repos

Trade-off

A monorepo with affected builds gives atomic cross-package changes and shared tooling, at the cost of graph and CI complexity. Many repos keep each pipeline simple, but a one-line change to a shared library becomes many version bumps and many deploys. Prefer a monorepo when packages change together every week. Prefer separate repos when ownership and release cadence really are independent.

Without affected-target logic, monorepo CI becomes a tax. Teams then fall back to long-lived branches. Build the graph early.

Common mistakes

  • Testing everything on every commit. CI cost grows with the whole repository, not with the change.
  • No remote cache. Every engineer and every run rebuilds the same artifacts.
  • A dependency graph that is out of date. Missing edges mean a change ships without its dependents being tested.

Check yourself

  1. A change touches only packages/billing in the graph above. What must rebuild? Answer: Only billing, because nothing imports it, so nothing else can break.
  2. Why does a remote cache help the second engineer? Answer: They reuse artifacts already built for the same commit, so they pay almost nothing.

Key takeaways

  • Run only the changed packages and their reverse dependents.
  • Bazel, Nx, Turborepo and Pants compute the graph and run affected targets.
  • A remote cache shares build results across machines.
  • Choose a monorepo when packages change together. Choose separate repos when they do not.

Further learning

Next, handle the tests that fail at random inside those affected targets: flaky tests. For how teams plan test coverage, see the testing strategy.