|$ curl https://forge-ai.dev/api/markdown?path=docs/build-tools/turborepo
$cat docs/turborepo.md
updated Today·24-32 min read·published

Turborepo

Build ToolsTurborepoMonorepoIntermediate🎯Free Tools
Introduction

Turborepo (turbo) is a high-performance build system for JavaScript/TypeScript monorepos. It does not replace Vite, Webpack, or tsup — it orchestrates their scripts with a dependency-aware pipeline, content-aware caching, and optional remote cache sharing across CI agents and laptops.

If you already use pnpm/npm/yarn workspaces and find yourself re-building unchanged packages on every PR, Turborepo is the usual next step. Reach for Nx when you also want generators, module boundaries, and a richer project graph UI.

info

Mental model: package managers link packages; bundlers compile packages; Turborepo schedules and caches package scripts.
Install & Workspace Layout
setup.sh
Bash
1# Root of a pnpm workspace monorepo
2pnpm add -Dw turbo
3
4# Typical layout
5# apps/web → Vite or Next app
6# apps/api → Node service
7# packages/ui → tsup library
8# packages/config → shared eslint/tsconfig
9# turbo.json
10# pnpm-workspace.yaml
pnpm-workspace.yaml
YAML
1packages:
2 - "apps/*"
3 - "packages/*"
Pipeline / Tasks

Declare tasks in turbo.json. dependsOn: ["^build"]means "build dependencies first" (the caret targets upstream packages).

turbo.json
JSON
1{
2 "$schema": "https://turbo.build/schema.json",
3 "tasks": {
4 "build": {
5 "dependsOn": ["^build"],
6 "outputs": ["dist/**", ".next/**", "!.next/cache/**"],
7 "env": ["NODE_ENV", "NEXT_PUBLIC_*"]
8 },
9 "test": {
10 "dependsOn": ["build"],
11 "outputs": ["coverage/**"]
12 },
13 "lint": {
14 "dependsOn": ["^build"]
15 },
16 "dev": {
17 "cache": false,
18 "persistent": true
19 },
20 "typecheck": {
21 "dependsOn": ["^build"],
22 "outputs": []
23 }
24 }
25}
FieldMeaningWhen to set
dependsOnTask graph edgesAlways for build/test ordering
outputsArtifacts restored from cacheAny task that writes files you reuse
env / passThroughEnvEnv vars that affect outputsPrevent false cache hits
cache: falseNever cachedev servers, deploy with side effects
persistentLong-running processdev / watch tasks

warning

Misdeclared outputs or missing env keys cause silent wrong cache hits. If a build depends on API_URL, list it or hashing will ignore it.
Local Caching

Turbo hashes inputs (files, deps, env, task definition). Matching hash → restore outputs and skip work. Local cache lives under .turbo.

run.sh
Bash
1# Run build across the workspace
2npx turbo run build
3
4# Only one package and its dependency graph
5npx turbo run build --filter=@acme/web...
6
7# Dry insight into what would run
8npx turbo run build --dry=json
9
10# Force ignore cache (debug)
11npx turbo run build --force
📝

note

Cache correctness depends on hermetic tasks. Avoid writing timestamps into artifacts or reading untracked files outside the package.
Remote Cache

Remote cache shares artifacts between CI jobs and developers. Vercel Remote Cache is the common hosted option; self-hosted / S3-compatible solutions exist via community or enterprise setups.

remote-cache.sh
Bash
1# Link to Vercel remote cache (interactive)
2npx turbo login
3npx turbo link
4
5# In CI, set token env vars (names per current Turbo docs)
6# TURBO_TOKEN=...
7# TURBO_TEAM=...
8
9npx turbo run build lint test --concurrency=4
BenefitHowWhen it pays off
PR CI minutes dropReuse main's build artifactsMany packages, frequent PRs
Laptop parityDevs pull remote hitsLarge apps with long builds
Cold runnersEmpty disk still hits remoteEphemeral GitHub Actions VMs

danger

Never put secrets into cached outputs. Remote caches are shared storage — treat artifact contents as potentially readable by anyone with cache access.
Filters & Affected Work

Filters select packages by name, directory, or git change set — critical for large repos on CI.

filters.sh
Bash
1# Single package
2turbo run build --filter=@acme/ui
3
4# Package + dependencies
5turbo run build --filter=@acme/web...
6
7# Package + dependents
8turbo run build --filter=...@acme/ui
9
10# Changed since main (pattern varies by turbo version)
11turbo run build --filter=...[origin/main]
12
13# Exclude
14turbo run build --filter=!@acme/docs
Package Scripts Convention

Turbo invokes the same script name in each package. Standardize names: build, dev, lint, test, typecheck.

packages/ui/package.json
JSON
1{
2 "name": "@acme/ui",
3 "scripts": {
4 "build": "tsup",
5 "dev": "tsup --watch",
6 "lint": "eslint .",
7 "typecheck": "tsc --noEmit",
8 "test": "vitest run"
9 }
10}
CI Integration
.github/workflows/ci.yml
YAML
1name: CI
2on:
3 push:
4 branches: [main]
5 pull_request:
6
7jobs:
8 build:
9 runs-on: ubuntu-latest
10 steps:
11 - uses: actions/checkout@v4
12 with:
13 fetch-depth: 0
14 - uses: pnpm/action-setup@v4
15 - uses: actions/setup-node@v4
16 with:
17 node-version: 22
18 cache: pnpm
19 - run: pnpm install --frozen-lockfile
20 - name: Turbo build
21 env:
22 TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
23 TURBO_TEAM: ${{ vars.TURBO_TEAM }}
24 run: pnpm turbo run build lint test --concurrency=2

best practice

Cache the pnpm store and use Turborepo remote cache. Install cache and task cache solve different layers of CI time.
Turborepo vs Nx (Brief)
AspectTurborepoNx
Core jobPipeline + cacheDev toolkit + graph + cache
Config weightLight (turbo.json)Heavier (project.json / nx.json)
GeneratorsMinimalFirst-class
Module boundariesConvention / ESLint DIYBuilt-in enforcement
Best fitExisting workspaces needing speedLarge orgs wanting structure
🔥

pro tip

Many teams start with Turborepo and adopt Nx later if boundary enforcement and codegen become daily needs. Starting with Nx is fine when you want that structure from day one.
Common Pitfalls
  • Forgetting ^build so apps compile against stale dependency sources.
  • Caching dev tasks (always disable).
  • Omitting env vars that change NEXT_PUBLIC_* embeds.
  • Output globs that miss nested artifacts → empty restores.
  • Running turbo without a lockfile-based install cache (still slow installs).
When to Adopt
SignalAction
2–3 packages, scripts already finepnpm -r may be enough
CI rebuilds everything every PRAdd Turborepo + remote cache
Need generators / boundariesPrefer Nx (or Nx + turbo-like caching)
$Blueprint — Engineering Documentation·Section ID: BT-TURBOREPO-01·Revision: 1.0

Community

Get help on Slack, Discord or VIP

Stuck on a guide? Join the community and ask.