vercel-turborepo
High-performance build system for JavaScript and TypeScript monorepos. Turborepo caches task outputs and runs tasks in parallel based on dependency graph, dramatically speeding up builds and enabling
Turborepo
High-performance build system for JavaScript and TypeScript monorepos. Turborepo caches task outputs and runs tasks in parallel based on dependency graph, dramatically speeding up builds and enabling efficient team collaboration.
Quick References
| File | Purpose |
|---|---|
packages/turbo/bin/turbo | CLI entry point (platform-aware binary wrapper) |
turbo.json | Root configuration file for task definitions and global settings |
packages/turbo-types/schemas/schema.v2.json | JSON schema for turbo.json validation and IDE autocomplete |
README.md | Project overview and getting started information |
When to Use
- Managing JavaScript/TypeScript codebases with multiple packages that share code
- Need to speed up CI/CD pipelines through intelligent caching and parallel execution
- Building applications that depend on shared libraries (UI components, utilities, configs)
- Developing multiple applications (web frontend, API, docs) in a single repository
- Running tests, linting, and builds across all packages efficiently
- Enabling team members to share build cache artifacts
Installation
# Install as a development dependency
npm install -D turbo
# or with pnpm
pnpm add -D turbo
# or with yarn
yarn add -D turbo
# Or run directly with npx (no install needed)
npx turbo run build
Best Practices
-
Always use
turbo runin code: In package.json scripts and CI workflows, useturbo run <task>instead of the shorthandturbo <task>. The shorthand is only for interactive terminal commands. -
Define tasks in packages, not root: Add scripts to each package's package.json and register them in root turbo.json. Root package.json should only delegate to
turbo run. -
Specify outputs for cacheable tasks: Always include
outputsin turbo.json for tasks that produce files. Without it, nothing is cached. -
Use workspace protocol for internal dependencies: Declare internal package dependencies with
"@repo/ui": "workspace:*"(pnpm/bun) or"*"(npm/yarn) so Turborepo can build in correct order. -
Avoid root
.envfiles: Place.envfiles in packages that need them. Root.envcreates unclear dependencies and invalidates cache unnecessarily. -
Prefer Package Configurations: For package-specific settings (framework outputs), use
turbo.jsonin each package with"extends": ["//"]instead of cluttering root config. -
Use
transitnodes for parallel tasks with cache awareness: Tasks likelintthat can run in parallel but must invalidate on dependency source changes need atransittask pattern.
Common Patterns
Basic monorepo setup with build and lint tasks:
// turbo.json
{
"$schema": "https://turborepo.dev/schema.v2.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**", "!.next/cache/**"]
},
"lint": {
"dependsOn": ["^lint"]
}
}
}
// packages/ui/package.json
{
"name": "@repo/ui",
"private": true,
"scripts": {
"build": "tsc",
"lint": "eslint ."
}
}
# Run build and lint across all packages
turbo run build lint
CI workflow with affected packages only:
# GitHub Actions
- name: Build
run: turbo run build --affected
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
Framework-specific package configurations:
// Root turbo.json
{
"$schema": "https://turborepo.dev/schema.v2.json",
"tasks": {
"build": {
"dependsOn": ["^build"]
}
}
}
// apps/web/turbo.json (Next.js app)
{
"extends": ["//"],
"tasks": {
"build": {
"outputs": ["$TURBO_EXTENDS$", ".next/**", "!.next/cache/**"]
}
}
}
Environment variables for caching:
{
"globalEnv": ["NODE_ENV", "CI"],
"globalDependencies": [".env"],
"tasks": {
"build": {
"env": ["API_URL", "NEXT_PUBLIC_*"],
"inputs": ["$TURBO_DEFAULT$", ".env*"],
"outputs": ["dist/**"]
}
}
}
Watch mode for development:
{
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
},
"dev": {
"cache": false,
"persistent": true,
"interruptible": true
}
}
}
turbo watch dev build
Docker sparse checkout:
turbo prune web --docker
# Creates Dockerfile and context for building just web package
API Quick Reference
| Export/Command | Type | Description |
|---|---|---|
turbo run <tasks> | CLI | Main entry point for running defined tasks across packages |
turbo watch <tasks> | CLI | Re-run tasks automatically when code changes |
turbo prune <pkg> | CLI | Create sparse checkout for Docker builds |
turbo link | CLI | Connect to Vercel Remote Cache |
turbo login | CLI | Authenticate with Remote Cache provider |
turbo ignore | CLI | Check if CI should skip based on changes |
turbo boundaries | CLI | Check for package boundary violations |
turbo generate | CLI | Scaffold new packages with generators |
create-turbo | CLI package | Create a new Turborepo monorepo |
@turbo/gen | TypeScript package | Types and utilities for code generators |
@turbo/types | TypeScript package | TypeScript types for turbo.json schemas |
@turbo/test-utils | TypeScript package | Testing utilities for Turborepo |
CLI Flags
| Flag | Description |
|---|---|
--filter=<pattern> | Select specific packages (e.g., web, ...web, ...^ui) |
--affected | Run only in packages changed since base branch |
--dry | Preview what would run without executing |
--force | Ignore all cached artifacts |
--concurrency=<n> | Limit parallel task execution |
--cache=<mode> | Control cache behavior (local:rw,remote:rw) |
--summarize | Generate JSON run summary for debugging |
--output-logs=<mode> | Control log verbosity (full, new-only, errors-only) |
--graph=<format> | Generate task graph visualization |
--env-mode=<mode> | Environment variable handling (strict, loose) |
turbo.json Configuration
| Key | Type | Description |
|---|---|---|
tasks | object | Task definitions and their behavior |
globalEnv | string[] | Environment variables affecting all task hashes |
globalDependencies | string[] | Files affecting all task hashes |
globalPassThroughEnv | string[] | Variables available to tasks but not in cache key |
cacheDir | string | Cache directory location (default: .turbo/cache) |
daemon | boolean | Background process for faster subsequent runs |
envMode | strict/loose | Environment variable handling mode |
ui | tui/stream | Terminal UI mode |
concurrency | string | Max parallel tasks (e.g., "4", "50%") |
remoteCache | object | Remote caching configuration |
Task Configuration
| Key | Type | Description |
|---|---|---|
dependsOn | string[] | Task dependencies (^build for dependencies' tasks) |
outputs | string[] | Glob patterns for files to cache |
inputs | string[] | Files considered for hash calculation |
env | string[] | Environment variables to include in hash |
passThroughEnv | string[] | Variables available but not in hash |
cache | boolean | Enable/disable caching (default: true) |
persistent | boolean | Long-running task doesn't exit |
interruptible | boolean | Allow restart on dependency changes |
interactive | boolean | Allow stdin input |
outputLogs | string | Log control (full, new-only, errors-only) |
with | string[] | Run tasks concurrently alongside this task |
description | string | Human-readable description |
Special Values
| Value | Meaning |
|---|---|
$TURBO_DEFAULT$ | Include default inputs, then add/remove |
$TURBO_ROOT$/<path> | Reference files from repo root |
$TURBO_EXTENDS$ | Append to inherited array value |
// | Reference root turbo.json in extends |
Environment Variables
| Variable | Purpose |
|---|---|
TURBO_TOKEN | Authentication token for remote cache |
TURBO_TEAM | Team identifier for remote cache |
TURBO_API | Custom remote cache API endpoint |
TURBO_BINARY_PATH | Override binary path (development use) |
TURBO_SCM_BASE | Base branch ref for --affected |
TURBO_SCM_HEAD | Head ref for --affected |
TURBO_REMOTE_CACHE_SIGNATURE_KEY | Key for artifact signing |