Partial Rebuilds: Only Building What Changed

How Turborepo determines what to rebuild — content hashing, dependency cascades, and remote caching across machines.

March 21, 20263 min read4 / 6

The full build cache is impressive. What's actually useful day-to-day is the partial rebuild — changing one package and having only the affected packages rebuild.

How the Cascade Works

Given this dependency graph:

Plain text
shared ← analytics shared ← users ← dashboard shared ← ui ← dashboard

If I change something in users, Turborepo rebuilds users and dashboard (which depends on users). Analytics is untouched — cache hit. The build that would have taken 5 seconds now takes 2.4 seconds, because one package rebuilt instead of four.

If I change something in shared, everything rebuilds. Every package depends on shared, so every package is potentially affected. That's the correct behavior — and importantly, it's the behavior you'd want verified in CI anyway.

The hashing mechanism is straightforward: Turborepo creates a content hash of all the source files in a package. If the hash matches what was cached, it skips the build. If not, it runs the build, produces new outputs, and caches the new hash. It's the same principle as CDN cache invalidation, applied to build artifacts.

The CI Impact

The case where this matters most is Playwright tests. End-to-end tests are slow. Running the full suite on every PR in a large monorepo is unsustainable — 17-minute CI runs kill developer velocity.

With Turborepo:

  • A change in users runs tests for users and dashboard only
  • A change in analytics runs tests for analytics only
  • A change in shared or ui runs everything (correctly — everything depends on them)

Teams working on isolated packages stop being slowed down by other teams' test suites. The design system team can change internal implementation without triggering 1000 Playwright tests they didn't author. Only if they change something that affects the API surface — and therefore affects consumers — does the cascade run.

This is one of the concrete advantages monorepos have over polyrepos that's hard to replicate otherwise. In a polyrepo, you don't know if changing the design system broke a downstream app until that app's team runs their CI. In a monorepo, you find out immediately.

Remote Caching

Local caching helps individuals. Remote caching helps teams.

With remote caching configured, if one developer (or a CI runner) has already built a particular version of a package, that cache is available to everyone. A second developer who pulls the same code and runs the build gets cache hits immediately — without running the build at all.

Turborepo's remote caching is a Vercel product, but they document open-source alternatives extensively. You can run your own caching server in a Docker container if you're not using Vercel. The configuration is one environment variable pointing at your cache server.

For a solo project, I still set it up. A push that triggers CI gets cache hits from my local build. CI runs in seconds because the work is already done.

Dependency Management with pnpm Catalog

A related problem that surfaces in larger monorepos: dependency version drift. Team A is on React 18.2, Team B is on 18.3, Team C upgraded to 19.0 last week. Users download multiple versions of the same library.

pnpm's catalog feature solves this at the package manager level:

YAML
# pnpm-workspace.yaml catalog: react: "^19.0.0" react-dom: "^19.0.0" typescript: "^5.8.0"

In each package's package.json:

JSON
{ "dependencies": { "react": "catalog:", "react-dom": "catalog:" } }

One place to update the React version. Every package in the monorepo picks it up. No version drift, no coordination overhead, no PRs just to bump a version number in 8 places.

If you're not on pnpm, the same idea can be implemented as a script or a CI check — a canonical versions file that gets applied across all package.json files. The pattern is the valuable part, not the specific tool.

Enjoyed this? Get more like it.

Deep dives on system design, React, web development, and personal finance — straight to your inbox. Free, always.