Running npm run build in a monorepo builds everything — even unchanged packages. Turborepo caches builds intelligently and runs tasks in parallel, cutting CI time from 30 minutes to 3.
What Turborepo Gives You for Free
- Remote caching — share build cache across your team and CI
- Parallel execution — build independent packages simultaneously
- Task pipelines — define dependencies between tasks
- Incremental builds — only rebuild what changed
- Pruned subsets — deploy only the packages you need
- Watch mode — efficient development across packages
Quick Start
npx create-turbo@latest
Configuration (turbo.json)
{
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**"]
},
"test": {
"dependsOn": ["build"]
},
"lint": {},
"dev": {
"cache": false,
"persistent": true
}
}
}
^build means: build dependencies FIRST, then build this package.
Monorepo Structure
my-monorepo/
├── apps/
│ ├── web/ # Next.js app
│ ├── mobile/ # React Native
│ └── api/ # Express server
├── packages/
│ ├── ui/ # Shared components
│ ├── utils/ # Shared utilities
│ ├── config/ # Shared configs
│ └── types/ # Shared TypeScript types
├── turbo.json
└── package.json
How Caching Works
# First run: builds everything
turbo build
# → web: cache miss, building...
# → ui: cache miss, building...
# → Total: 45s
# Second run: nothing changed
turbo build
# → web: cache hit, replaying logs
# → ui: cache hit, replaying logs
# → Total: 0.3s ← 150x faster!
# After changing packages/ui:
turbo build
# → ui: cache miss, rebuilding (changed)
# → web: cache miss, rebuilding (depends on ui)
# → api: cache hit (doesn't depend on ui)
# → Total: 15s ← Only rebuilds affected packages
Remote Caching (Team Sharing)
# Login to Vercel (free)
npx turbo login
# Link your repo
npx turbo link
# Now builds are shared:
# Developer A builds → cache uploaded
# Developer B runs same build → cache downloaded (instant)
# CI runs same build → cache downloaded (instant)
Filtering (Run Tasks for Specific Packages)
# Build only the web app and its dependencies
turbo build --filter=web
# Test only packages that changed since main
turbo test --filter=...[main]
# Lint only packages in apps/
turbo lint --filter=./apps/*
Pruned Docker Builds
# Generate pruned workspace for deployment
turbo prune web --docker
# Creates:
# out/
# json/ → package.json files only (for install)
# full/ → full source (for build)
# Dockerfile
FROM node:20-alpine AS installer
COPY out/json/ .
RUN npm install
FROM installer AS builder
COPY out/full/ .
RUN turbo build --filter=web
FROM node:20-alpine
COPY --from=builder /app/apps/web/.next .next
CMD ["node", "server.js"]
Turborepo vs Nx vs Lerna
| Feature | Turborepo | Nx | Lerna |
|---|---|---|---|
| Setup | 1 file | Complex | Medium |
| Remote cache | Vercel (free) | Nx Cloud | None |
| Task orchestration | Built-in | Built-in | Basic |
| Code generation | None | Extensive | None |
| Bundle size | Tiny | Large | Medium |
| Learning curve | 10 min | 1+ hour | 30 min |
The Verdict
Turborepo makes monorepos fast without making them complex. One config file, intelligent caching, and parallel execution. If your monorepo builds are slow, Turborepo is the simplest fix.
Need help building production web scrapers or data pipelines? I build custom solutions. Reach out: spinov001@gmail.com
Check out my awesome-web-scraping collection — 400+ tools for extracting web data.
Top comments (0)