Your monorepo CI takes 20 minutes. Every PR rebuilds every package — even packages you didn't touch. You tried Lerna, it's slow. You tried Nx, it's complex. You just want fast builds.
What if your build system knew exactly which packages changed and only rebuilt those — with remote caching for free?
That's Turborepo.
Quick Start
npx create-turbo@latest
cd my-turborepo && npm run build
How Turborepo Works
// turbo.json
{
"$schema": "https://turbo.build/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**"]
},
"test": {
"dependsOn": ["build"]
},
"lint": {},
"dev": {
"cache": false,
"persistent": true
}
}
}
When you run turbo build:
- Turborepo analyzes your dependency graph
- Builds packages in parallel (respecting dependencies)
- Caches outputs — next build of unchanged packages takes 0 seconds
- Only rebuilds what actually changed
The Impact
# First build — full run
$ turbo build
# ✓ @repo/ui: build (2.1s)
# ✓ @repo/utils: build (1.3s)
# ✓ web: build (8.7s)
# ✓ docs: build (5.2s)
# Total: 12.1s (parallelized)
# Second build — nothing changed
$ turbo build
# ✓ @repo/ui: build (FULL TURBO - 12ms)
# ✓ @repo/utils: build (FULL TURBO - 8ms)
# ✓ web: build (FULL TURBO - 15ms)
# ✓ docs: build (FULL TURBO - 11ms)
# Total: 46ms
From 12 seconds to 46 milliseconds. That's what caching gives you.
Remote Caching — Share Cache Across CI and Team
npx turbo login
npx turbo link
Now your CI and every developer share the same cache. Developer A builds @repo/ui → Developer B gets the cached result instantly. CI doesn't rebuild what a developer already built locally.
Monorepo Structure
my-turborepo/
apps/
web/ ← Next.js app
docs/ ← Documentation site
mobile/ ← React Native app
packages/
ui/ ← Shared component library
utils/ ← Shared utilities
config/ ← Shared ESLint, TypeScript configs
database/ ← Prisma schema + client
turbo.json
package.json
Filtering — Run Tasks for Specific Packages
# Build only the web app and its dependencies
turbo build --filter=web
# Run tests only for packages that changed since main
turbo test --filter=...[main]
# Lint only packages in the packages/ directory
turbo lint --filter=./packages/*
CI Integration
# .github/workflows/ci.yml
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npm install
- run: npx turbo build test lint --filter=...[HEAD^1]
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
Only builds/tests packages affected by the latest commit. With remote cache, most tasks complete in milliseconds.
When to Choose Turborepo
Choose Turborepo when:
- Your monorepo builds are slow and you want quick wins
- You want simple setup (turbo.json + done)
- Remote caching is valuable (teams, CI)
- You use npm/pnpm/yarn workspaces
Skip Turborepo when:
- Single-package repo (no benefit)
- You need advanced code generation or graph visualization (Nx does more)
- You need non-JS package management (Bazel handles polyglot repos)
The Bottom Line
Turborepo does one thing — make monorepo builds fast — and does it with minimal configuration. Add turbo.json, run turbo build, watch your CI time drop by 80%.
Start here: turbo.build
Need custom data extraction, scraping, or automation? I build tools that collect and process data at scale — 78 actors on Apify Store and 265+ open-source repos. Email me: Spinov001@gmail.com | My Apify Actors
Top comments (0)