Why I Rewrote Our Build System (And What I Learned)
Our build system was six years old. It worked — in the same way a 1998 Honda Civic with 300,000 miles “works”. You could get from A to B, but every journey carried existential dread.
The legacy system
Here’s what we were dealing with:
Before migrating any build system in production, make sure you have at least one week of baseline metrics: build times, cache hit rates, failure rates. You cannot prove improvement without a baseline.
Why Turborepo
I evaluated three options:
| Tool | Remote cache | Incremental | Learning curve |
|---|---|---|---|
| Turborepo | ✅ native | ✅ task-level | Low |
| Nx | ✅ | ✅ project-level | Medium |
| Bazel | ✅ | ✅ file-level | Extreme |
For a team of 12 engineers who needed to be productive from day one, Turborepo was the obvious choice.
The migration
Audit your task graph
Before writing a single line of config, map your build graph manually. I used a whiteboard and coloured markers.
Set up the workspace
{
"$schema": "https://turbo.build/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**"]
}
}
}Migrate scripts incrementally
Never do a big-bang migration. Wrap each old script in a Turbo task one at a time, verify behaviour matches, merge.
Enable remote caching
This is where the real wins appear. Our CI went from 23 minutes to 4 minutes on cache hits.
Results
The numbers:
- Mean CI time: 23 min → 4 min (83% reduction)
- Cache hit rate (month 3): 84%
What surprised me
The biggest surprise was not the time savings. It was the psychological effect on the team. When builds are fast, engineers run them more often. When engineers run them more often, they catch bugs earlier. The feedback loop compounds.
Fast builds are a culture investment, not just a tooling investment.