Turborepo - Quick Reference
Deep Knowledge: Use mcp__documentation__fetch_docs with technology: turborepo for comprehensive documentation.
When NOT to Use This Skill
-
Nx monorepos - Use nx skill for Nx-specific features
-
Single package projects - No need for monorepo tools
-
Need advanced generators - Nx has better code generation
-
Complex module boundaries - Nx enforces them better
When to Use This Skill
-
Monorepo with multiple packages
-
Build caching and optimization
-
CI/CD for monorepos
-
Complex task orchestration
Setup
New monorepo
npx create-turbo@latest my-monorepo
Add to existing monorepo
npm install turbo --save-dev
Project Structure
my-monorepo/ ├── turbo.json ├── package.json ├── apps/ │ ├── web/ │ │ └── package.json │ └── api/ │ └── package.json └── packages/ ├── ui/ │ └── package.json ├── config/ │ └── package.json └── utils/ └── package.json
Configuration (turbo.json)
{ "$schema": "https://turbo.build/schema.json", "tasks": { "build": { "dependsOn": ["^build"], "outputs": ["dist/", ".next/", "build/"] }, "dev": { "cache": false, "persistent": true }, "lint": { "dependsOn": ["^build"] }, "test": { "dependsOn": ["build"], "outputs": ["coverage/"] }, "typecheck": { "dependsOn": ["^build"] } } }
Task Configuration
{ "tasks": { "build": { // Run dependencies' build first "dependsOn": ["^build"],
// Files that affect cache
"inputs": [
"src/**",
"package.json",
"tsconfig.json"
],
// Outputs to cache
"outputs": ["dist/**"],
// Environment variables that affect cache
"env": ["NODE_ENV", "API_URL"],
// Pass-through env vars (not cached)
"passThroughEnv": ["CI", "GITHUB_TOKEN"]
},
"dev": {
// Don't cache dev tasks
"cache": false,
// Keep running (watch mode)
"persistent": true
},
"deploy": {
// Run after build
"dependsOn": ["build"],
// No outputs
"outputs": []
}
} }
Running Tasks
Run task in all packages
turbo build turbo lint turbo test
Run in specific package
turbo build --filter=@myorg/web turbo build --filter=web
Run in multiple packages
turbo build --filter=@myorg/web --filter=@myorg/api
Run with dependencies
turbo build --filter=@myorg/web... # web + its dependencies turbo build --filter=...@myorg/ui # ui + its dependents
Since git ref
turbo build --filter=[HEAD^1] # Changed since last commit turbo build --filter=[origin/main] # Changed since main
Parallel execution
turbo dev
Dry run
turbo build --dry-run turbo build --graph # Output dependency graph
Package Configuration
// apps/web/package.json { "name": "@myorg/web", "scripts": { "build": "next build", "dev": "next dev", "lint": "eslint .", "test": "vitest run" }, "dependencies": { "@myorg/ui": "", "@myorg/utils": "" } }
// packages/ui/package.json { "name": "@myorg/ui", "scripts": { "build": "tsup src/index.ts --dts", "dev": "tsup src/index.ts --watch", "lint": "eslint ." } }
Root package.json
{ "name": "my-monorepo", "private": true, "workspaces": ["apps/", "packages/"], "scripts": { "build": "turbo build", "dev": "turbo dev", "lint": "turbo lint", "test": "turbo test", "typecheck": "turbo typecheck", "clean": "turbo clean && rm -rf node_modules" }, "devDependencies": { "turbo": "^2.0.0" } }
Caching
Local Cache
Cache stored in node_modules/.cache/turbo
Force fresh build
turbo build --force
View cache status
turbo build --summarize
Remote Cache (Vercel)
Login to Vercel
turbo login
Link to remote cache
turbo link
Now builds use remote cache
turbo build
Self-hosted Remote Cache
// turbo.json { "remoteCache": { "enabled": true, "signature": true } }
Use custom remote cache
TURBO_API="https://your-cache-server.com"
TURBO_TOKEN="your-token"
TURBO_TEAM="your-team"
turbo build
Environment Variables
// turbo.json { "globalEnv": ["CI", "NODE_ENV"], "globalPassThroughEnv": ["GITHUB_TOKEN"], "tasks": { "build": { "env": ["API_URL", "DATABASE_URL"], "passThroughEnv": ["VERCEL_URL"] } } }
.env Files
// turbo.json { "globalDotEnv": [".env"], "tasks": { "build": { "dotEnv": [".env.production", ".env.local"] } } }
CI/CD
GitHub Actions
name: CI
on: push: branches: [main] pull_request:
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 2 # Needed for --filter=[HEAD^1]
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install
run: npm ci
- name: Build
run: npx turbo build --filter=[HEAD^1]
- name: Test
run: npx turbo test --filter=[HEAD^1]
- name: Lint
run: npx turbo lint --filter=[HEAD^1]
With Remote Cache
- name: Build run: npx turbo build env: TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} TURBO_TEAM: ${{ vars.TURBO_TEAM }}
Package-specific Config
// apps/web/turbo.json { "extends": ["//"], "tasks": { "build": { "outputs": [".next/", "!.next/cache/"] } } }
Generators
Create generator
turbo gen init
Run generator
turbo gen workspace
// turbo/generators/config.ts import { PlopTypes } from "@turbo/gen";
export default function generator(plop: PlopTypes.NodePlopAPI): void { plop.setGenerator("package", { description: "Create a new package", prompts: [ { type: "input", name: "name", message: "Package name?", }, ], actions: [ { type: "add", path: "packages/{{name}}/package.json", templateFile: "templates/package.json.hbs", }, ], }); }
Task Dependencies
{ "tasks": { // topological: run in dependencies first "build": { "dependsOn": ["^build"] },
// same package: run after
"test": {
"dependsOn": ["build"]
},
// specific package
"deploy": {
"dependsOn": ["@myorg/web#build", "@myorg/api#build"]
},
// no dependencies
"lint": {
"dependsOn": []
}
} }
Debugging
Verbose output
turbo build --verbosity=2
Dry run
turbo build --dry-run=json
Graph visualization
turbo build --graph=graph.html
Summarize
turbo build --summarize
Profile
turbo build --profile=profile.json
Comparison: Turborepo vs Nx
Feature Turborepo Nx
Setup Simple Complex
Config JSON TypeScript
Caching Excellent Excellent
Task runner Fast Fast
Generators Basic Advanced
Plugins Limited Extensive
Learning curve Low Medium
Vercel integration Native Manual
When to Use
Scenario Recommendation
Simple monorepo Turborepo
Complex enterprise Nx
Vercel deployment Turborepo
Need generators Nx
Quick setup Turborepo
Anti-Patterns to Avoid
-
Do not forget --filter for incremental builds
-
Do not cache tasks with side effects
-
Do not ignore outputs configuration
-
Do not use * in workspace dependencies (use workspace protocol)
Anti-Patterns
Anti-Pattern Why It's Bad Correct Approach
Not using --filter Rebuilds everything Use --filter for affected packages
Caching side effects Unreliable deployments Set cache: false for deploy tasks
Missing outputs Cache doesn't work Declare all output directories
Using * for workspace deps Version conflicts Use workspace:* protocol
No remote cache in CI Slow CI builds Setup Vercel or self-hosted cache
Forgetting env in turbo.json Cache misses Declare env vars that affect output
Quick Troubleshooting
Issue Cause Solution
Cache always misses Missing outputs Add outputs to turbo.json task
Task runs when shouldn't Wrong dependsOn Check ^build syntax for dependencies
Slow builds Not using cache Enable remote cache or check outputs
Wrong execution order Missing dependsOn Add dependsOn: ["^build"]
Env vars not working Not declared Add to env or passThroughEnv
Remote cache not working Auth issue Check TURBO_TOKEN and TURBO_TEAM
Checklist
-
turbo.json with task definitions
-
^build for topological dependencies
-
outputs configured for caching
-
env vars declared
-
Remote cache for CI
-
--filter for incremental builds
Further Reading
For advanced configurations: mcp__documentation__fetch_docs
-
Technology: turborepo
-
Turborepo Docs