# The Practical Vercel Turborepo Cheatsheet

Canonical URL: https://www.harjotrana.com/blog/turborepo-cheatsheet
Author: Harjot Singh Rana
Published: 2025-12-08
Reading time: 23 min

> Task graphs, remote caching, and the pipeline config that actually keeps a monorepo fast.

**Turborepo** is a build system optimized for JavaScript and TypeScript monorepos, written in Rust. It handles task orchestration, caching, and dependency management across multiple packages in a single repository.

---

## Core Concepts

### Monorepo Structure

```text
my-monorepo/
├── apps/
│   ├── web/
│   ├── mobile/
│   └── admin/
├── packages/
│   ├── ui-library/
│   ├── utils/
│   └── types/
├── turbo.json (configuration)
├── package.json (root workspace)
└── pnpm-workspace.yaml (or package.json for npm/yarn workspaces)
```

### Key Concepts

- **Package Graph**: Relationship between all packages in the monorepo
- **Task Graph**: Dependency relationships between tasks
- **Caching**: Turborepo remembers task outputs and reuses them when inputs haven't changed
- **Remote Caching**: Share cache artifacts across team members and CI/CD systems

---

## Installation & Setup

### Initialize a New Turborepo

```bash
npx create-turbo@latest
```

### Add Turborepo to Existing Project

```bash
npm install turbo --save-dev

# Initialize configuration
turbo init
```

---

## turbo.json Configuration

### Basic Structure

```json
{
  "extends": ["//"],
  "globalDependencies": ["*.env", "package.json"],
  "globalEnv": ["NODE_ENV"],
  "globalPassThroughEnv": ["HOME", "PATH"],
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**", ".next/**"],
      "cache": true,
      "env": ["NODE_ENV", "API_*"]
    },
    "test": {
      "dependsOn": ["build"],
      "outputs": ["coverage/**"],
      "cache": true
    },
    "dev": {
      "cache": false,
      "persistent": true,
      "interactive": true
    },
    "lint": {
      "outputs": []
    }
  }
}
```

### Task Definition Options

| Option | Description | Example |
|--------|-------------|---------|
| `dependsOn` | Tasks that must complete first | `["^build"]`, `["build", "lint"]` |
| `outputs` | Files to cache | `["dist/**", ".next/**"]` |
| `cache` | Enable/disable caching | `true` or `false` |
| `env` | Environment variables that affect hashing | `["NODE_ENV", "API_*"]` |
| `passThroughEnv` | Environment variables available but not cached | `["HOME"]` |
| `inputs` | Files to consider for cache invalidation | `["src/**", "package.json"]` |
| `persistent` | Mark as long-running (dev servers) | `true` |
| `interactive` | Accept stdin input | `true` |
| `interruptible` | Allow restart by turbo watch | `true` |
| `outputLogs` | Log verbosity | `"full"`, `"hash-only"`, `"new-only"`, `"errors-only"`, `"none"` |

### Dependency Prefix Symbols

| Symbol | Meaning | Example |
|--------|---------|---------|
| `^` | Depends on same task in dependencies | `"^build"` (wait for deps to build) |
| No prefix | Same-package dependency | `"build"` (in test task = test after build in same pkg) |
| `package#task` | Specific package task | `"utils#build"` (utils package build task) |

---

## Common turbo.json Patterns

### Pattern 1: Build with Dependencies

```json
{
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**", ".next/**"]
    }
  }
}
```

Builds dependencies first, then this package.

### Pattern 2: Test Before Build

```json
{
  "pipeline": {
    "build": {
      "dependsOn": ["test", "^build"],
      "outputs": ["dist/**"]
    }
  }
}
```

Runs local tests, then dependency builds, then this package build.

### Pattern 3: Cache-Only Tasks

```json
{
  "pipeline": {
    "test": {
      "cache": true,
      "outputs": ["coverage/**"]
    }
  }
}
```

Tests are cached; only re-run on source code changes.

### Pattern 4: Never Cache

```json
{
  "pipeline": {
    "deploy": {
      "cache": false
    }
  }
}
```

Useful for deployment and external API calls.

### Pattern 5: Long-Running Tasks (Dev Server)

```json
{
  "pipeline": {
    "dev": {
      "cache": false,
      "persistent": true,
      "interactive": true
    }
  }
}
```

Dev servers run continuously and accept input.

---

## CLI Commands

### Run Tasks

```bash
# Run a single task in all packages
turbo run build

# Run multiple tasks
turbo run build lint test

# Run task in specific package
turbo run build --filter=ui

# Run without dependencies (immediate task only)
turbo run test --only

# Run only affected packages (git-based)
turbo run build --affected

# Run with all environment variables available
turbo run build --env-mode=loose

# Run in parallel (ignoring dependency graph)
turbo run dev --parallel

# Force re-run (ignore cache)
turbo run build --force

# Run with verbose output
turbo run build -v
turbo run build -vv   # more verbose
turbo run build -vvv  # very verbose
```

### Filtering

```bash
# By package name
turbo run build --filter=web

# By directory pattern
turbo run build --filter=./apps/*

# By git changes
turbo run build --filter=[HEAD^1]

# Select dependents (packages depending on target)
turbo run build --filter=...ui

# Select dependencies (packages target depends on)
turbo run build --filter=ui...

# Exclude packages
turbo run build --filter=!admin

# Combine filters (union)
turbo run build --filter=web --filter=mobile

# Specific task in package
turbo run web#build
```

### Cache Management

```bash
# Disable caching
turbo run build --no-cache

# Use only local cache
turbo run build --cache=local:rw

# Use only remote cache
turbo run build --cache=remote:rw

# Read-only cache
turbo run build --cache=local:r

# Disable cache completely
turbo run build --cache=local:,remote:
```

### Other Useful Commands

```bash
# Dry run (show what would execute, don't run)
turbo run build --dry-run

# Dry run as JSON
turbo run build --dry=json

# Show task execution order without running
turbo run build --graph=mermaid

# Generate performance trace (Chrome Tracing format)
turbo run build --profile -vv

# Generate run summary (metadata about execution)
turbo run build --summarize

# Continue on error
turbo run build --continue=always

# Limit concurrency
turbo run build --concurrency=4
turbo run build --concurrency=50%

# Watch mode (watch for changes and re-run)
turbo watch run build
```

### Remote Caching (Vercel)

```bash
# Login to Vercel
turbo login

# Link to remote cache
turbo link

# Link specific project in package
cd apps/web && turbo link

# Logout
turbo logout

# Verify remote cache is working
turbo run build --summarize
```

### Utility Commands

```bash
# List all packages in workspace
turbo ls

# Check workspace info
turbo info

# Check package boundaries/dependencies
turbo boundaries

# Generate new package/code
turbo gen

# Prune dependency graph (for Docker/CI)
turbo prune --scope=web

# Check for missing environment variables
turbo scan

# Get Turborepo version
turbo --version
```

---

## Environment Variables

### Global Environment Variables (turbo.json)

```json
{
  "globalEnv": ["NODE_ENV", "API_KEY"],
  "globalPassThroughEnv": ["HOME", "PATH"]
}
```

- `globalEnv`: Changes invalidate ALL task caches
- `globalPassThroughEnv`: Available to tasks but don't affect caching

### Task-Specific Environment Variables

```json
{
  "pipeline": {
    "build": {
      "env": ["NODE_ENV", "NEXT_PUBLIC_*"],
      "passThroughEnv": ["HOME"]
    }
  }
}
```

### Environment Variable Patterns

```json
{
  "env": [
    "*",                 // All variables
    "API_*",            // Prefix match
    "!API_SECRET",      // Negation (exclude)
    "NODE_ENV"          // Exact match
  ]
}
```

### Strict vs Loose Mode

```bash
# Strict mode (default) - only listed vars available
turbo run build --env-mode=strict

# Loose mode - all vars available (less safe for caching)
turbo run build --env-mode=loose
```

---

## Package Configurations

Use for task customization per-package:

```json
// packages/ui/turbo.json
{
  "extends": ["//"],
  "pipeline": {
    "build": {
      "outputs": ["dist/**"],
      "env": ["THEME_*"]
    }
  }
}
```

---

## Common Patterns & Best Practices

### 1. Workspace Dependencies

```json
// apps/web/package.json
{
  "dependencies": {
    "@repo/ui": "workspace:*",
    "@repo/utils": "workspace:*"
  }
}
```

### 2. Shared Configuration

```json
// Root turbo.json
{
  "globalDependencies": [
    "package.json",
    "pnpm-lock.yaml",
    ".env.example"
  ]
}
```

### 3. CI/CD Optimization

```bash
# In GitHub Actions
turbo run build --affected --cache=remote:rw

# In other CI systems
turbo run build --force --cache=local:rw
```

### 4. Docker/Monorepo Pruning

```bash
# Prune only dependencies needed for `web` app
turbo prune --scope=web --docker

# Then in Dockerfile
COPY --from=base /repo/out/full /repo
COPY --from=base /repo/out/json . 
COPY --from=base /repo/out/pnpm-lock.yaml ./pnpm-lock.yaml
RUN pnpm install --frozen-lockfile
```

### 5. Task Skipping (turbo-ignore)

```bash
# In CI environment variable
TURBO_TELEMETRY_DISABLED=1

# Skip build if only docs changed
turbo-ignore docs
```

---

## Caching Strategy

### What Gets Cached

- **Outputs**: Files specified in `outputs` key
- **Logs**: Task logs (always cached if caching enabled)
- **Metadata**: Task execution metadata

### Cache Invalidation

Cache is invalidated when:

- Source files in `inputs` change
- `globalDependencies` files change
- Environment variables in `env` change
- `turbo.json` changes
- `package.json` changes (in that package)
- Lockfile changes

### Cache Locations

```bash
# Local cache (default)
.turbo/cache/

# Custom cache directory
turbo run build --cache-dir=.turbo-cache

# Or in turbo.json
{
  "cacheDir": ".turbo-cache"
}
```

---

## Debugging & Troubleshooting

### Check Task Configuration

```bash
# See what tasks will execute
turbo run build --dry-run

# Get detailed execution info
turbo run build --dry=json | jq

# Verbose output
turbo run build -vvv
```

### Analyze Performance

```bash
# Generate Chrome trace
turbo run build --profile -vv

# Check hash and dependencies
turbo run build --dry-run | grep -A5 "web#build"

# See execution summary
turbo run build --summarize
# View in `.turbo/runs/` directory
```

### Common Issues

| Issue | Solution |
|-------|----------|
| Cache not working | Check `outputs` glob pattern; verify env vars in `env` key |
| Task not running | Check `dependsOn`; use `--dry-run` to verify task graph |
| Environment vars not available | Add to `env` in turbo.json for hashing, `passThroughEnv` for availability |
| Performance degradation | Check if inputs are too broad; optimize glob patterns |
| Package not found | Verify `package.json` name; use `turbo ls` to list packages |

---

## Advanced Tips

### 1. Framework Inference

Turborepo automatically includes framework-specific env vars:

- Next.js: `NEXT_PUBLIC_*` (automatic)
- Nuxt: `NUXT_*` (automatic)
- Vue: `VUE_APP_*` (automatic)

### 2. Multiple Package Managers

```json
{
  "packageManager": "pnpm@8.0.0"
}
```

### 3. Workspace Configuration

```json
// pnpm-workspace.yaml
packages:
  - 'apps/*'
  - 'packages/*'
  - 'tools/*'
```

```json
// package.json (npm/yarn)
{
  "workspaces": ["apps/*", "packages/*"]
}
```

### 4. Remote Cache with Custom Endpoint

```json
{
  "remoteCache": {
    "apiUrl": "https://custom-cache.com",
    "signature": true,
    "timeout": 60,
    "uploadTimeout": 120
  }
}
```

### 5. Concurrency Control

```bash
# Serial execution (1 at a time)
turbo run build --concurrency=1

# Use 50% of CPU cores
turbo run build --concurrency=50%

# Or in turbo.json
{
  "concurrency": "50%"
}
```

---

## Real-World Example

```json
{
  "extends": ["//"],
  "globalDependencies": ["*.env", "package.json"],
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**", ".next/**"],
      "cache": true,
      "env": ["NODE_ENV", "API_URL"]
    },
    "test": {
      "dependsOn": ["build"],
      "outputs": ["coverage/**"],
      "cache": true
    },
    "lint": {
      "cache": true,
      "outputs": []
    },
    "type-check": {
      "cache": true,
      "outputs": []
    },
    "dev": {
      "cache": false,
      "persistent": true,
      "interactive": true
    },
    "deploy": {
      "cache": false,
      "dependsOn": ["build", "test", "lint"]
    }
  }
}
```

### Usage:

```bash
# Full CI pipeline
turbo run lint type-check test build

# Development
turbo run dev --parallel

# Deploy only changed packages
turbo run build --affected && turbo run deploy

# Rebuild everything
turbo run build --force
```

---

## Resources

- **Official Docs**: https://turborepo.com
- **API Reference**: https://turborepo.com/docs/reference
- **Examples**: https://github.com/vercel/turborepo/tree/main/examples
- **Vercel Remote Cache**: https://vercel.com/docs/monorepos/turborepo

---

## Quick Command Reference

```bash
# Development
turbo run dev --parallel

# Build
turbo run build

# Lint
turbo run lint

# Test
turbo run test

# All checks before commit
turbo run lint type-check test

# Force rebuild everything
turbo run build --force

# Only affected packages
turbo run build --affected

# Specific package
turbo run build --filter=web

# Watch mode
turbo watch run build

# See what would run
turbo run build --dry-run

# Performance analysis
turbo run build --profile -vv

# Remote cache
turbo login
turbo link
turbo run build
```

_Last Updated: December 2025 | Based on Turborepo latest documentation_

More writing: https://www.harjotrana.com/blog

---

Site guide for agents: https://www.harjotrana.com/llms.txt · Full site as Markdown: https://www.harjotrana.com/llms-full.txt · Sitemap: https://www.harjotrana.com/sitemap.xml · Developer resources: https://www.harjotrana.com/developers