turborepo

Turborepo is a high-performance build system for JavaScript/TypeScript monorepos. It provides intelligent caching, parallel execution, and incremental builds.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "turborepo" with this command: npx skills add fractionestate/midnight-dev-skills/fractionestate-midnight-dev-skills-turborepo

Turborepo

Turborepo is a high-performance build system for JavaScript/TypeScript monorepos. It provides intelligent caching, parallel execution, and incremental builds.

Core Concepts

Monorepo Structure

my-turborepo/ ├── apps/ │ ├── web/ # Next.js app │ │ ├── package.json │ │ └── next.config.js │ └── docs/ # Documentation site │ └── package.json ├── packages/ │ ├── ui/ # Shared component library │ │ ├── package.json │ │ └── src/ │ ├── config/ # Shared configs (ESLint, TS, etc.) │ │ └── package.json │ └── utils/ # Shared utilities │ └── package.json ├── turbo.json # Turborepo configuration ├── package.json # Root package.json └── pnpm-workspace.yaml # Workspace definition

turbo.json Configuration

{ "$schema": "https://turborepo.com/schema.json", "ui": "stream", "envMode": "strict", "tasks": { "build": { "dependsOn": ["^build"], "inputs": ["$TURBO_DEFAULT$", ".env*"], "outputs": [".next/", "!.next/cache/", "dist/"], "env": ["NODE_ENV", "DATABASE_URL", "NEXT_PUBLIC_*"] }, "dev": { "cache": false, "persistent": true, "interactive": true }, "lint": { "dependsOn": ["^build"], "outputs": [] }, "test": { "dependsOn": ["build"], "inputs": ["src/", "test/"], "outputs": ["coverage/"] }, "typecheck": { "dependsOn": ["^build"], "outputs": [] } } }

Workspace Package.json

{ "name": "my-turborepo", "private": true, "scripts": { "build": "turbo run build", "dev": "turbo run dev", "lint": "turbo run lint", "test": "turbo run test", "typecheck": "turbo run typecheck", "clean": "turbo run clean && rm -rf node_modules" }, "devDependencies": { "turbo": "^2.7.2" }, "packageManager": "pnpm@10.26.0" }

pnpm-workspace.yaml

packages:

  • 'apps/*'
  • 'packages/*'

Task Configuration

Dependency Types

{ "tasks": { // Topological dependency (dependencies first) "build": { "dependsOn": ["^build"] // Run build in all dependencies first },

// Same-package dependency
"test": {
  "dependsOn": ["build"] // Run build in same package first
},

// Cross-package specific dependency
"deploy": {
  "dependsOn": ["build", "test", "^build"]
},

// Arbitrary package#task dependency
"e2e": {
  "dependsOn": ["web#build", "api#build"] // Specific packages
}

} }

Input/Output Configuration

{ "tasks": { "build": { // Files that affect cache "inputs": [ "$TURBO_DEFAULT$", // Default: all non-gitignored files "!README.md", // Exclude README changes ".env.production", // Include specific env file "$TURBO_ROOT$/tsconfig.json" // Reference files from repo root ], // Files produced by task "outputs": [ "dist/", ".next/", "!.next/cache/**" // Exclude .next/cache ] } } }

Note: The following files are always considered inputs and cannot be ignored:

  • package.json

  • turbo.json

  • Package manager lockfiles (automatically included in global hash)

Environment Variables

{ "globalEnv": ["CI", "VERCEL"], "globalPassThroughEnv": ["AWS_ACCESS_KEY"], "tasks": { "build": { "env": [ "DATABASE_URL", "NEXT_PUBLIC_", // Wildcard: all vars starting with NEXT_PUBLIC_ "!GITHUB_" // Negation: exclude GITHUB_ vars from strict mode ], "passThroughEnv": ["AWS_SECRET_KEY"] // Available but not in cache hash } } }

Caching

Local Caching

Cache stored in node_modules/.cache/turbo

turbo run build

Force cache miss

turbo run build --force

Remote Caching

Login to Vercel Remote Cache

npx turbo login

Link project

npx turbo link

Or use custom cache server

TURBO_API="https://cache.example.com" TURBO_TOKEN="your-token" TURBO_TEAM="your-team"

Cache Configuration

{ "tasks": { "build": { "cache": true, // Enable caching (default) "outputLogs": "new-only" // Show logs only on cache miss }, "dev": { "cache": false, // Disable caching for dev "persistent": true, // Long-running task "interactive": true // Accepts keyboard input (stdin) }, "db:studio": { "cache": false, "persistent": true, "interruptible": true // Can be restarted when dependencies change } } }

Development Mode

turbo watch

Re-run tasks automatically when files change:

Watch all tasks

turbo watch build lint typecheck

Watch specific packages

turbo watch build --filter=web

Write cache in watch mode (experimental)

turbo watch build --experimental-write-cache

Watch mode is dependency-aware - when a package changes, all dependent packages re-run their tasks. Persistent tasks (dev servers) are automatically handled.

Docker Optimization

turbo prune

Generate a partial monorepo for efficient Docker builds:

Basic prune

turbo prune web

Docker-optimized output (recommended)

turbo prune web --docker

The --docker flag creates:

  • out/json/

  • package.json files only (for dependency layer)

  • out/full/

  • Complete pruned workspace (for build layer)

Dockerfile Pattern

FROM node:22-alpine AS builder WORKDIR /app

Install turbo globally

RUN npm install -g turbo

Copy all files and prune

COPY . . RUN turbo prune web --docker

Install dependencies (cached layer)

FROM node:22-alpine AS installer WORKDIR /app COPY --from=builder /app/out/json/ . RUN npm install

Build the app

COPY --from=builder /app/out/full/ . RUN npx turbo run build --filter=web

Production image

FROM node:22-alpine AS runner WORKDIR /app COPY --from=installer /app/apps/web/.next/standalone ./ COPY --from=installer /app/apps/web/.next/static ./apps/web/.next/static COPY --from=installer /app/apps/web/public ./apps/web/public

CMD ["node", "apps/web/server.js"]

Filtering

Package Filters

Run build only in web app

turbo run build --filter=web

Run in web and its dependencies

turbo run build --filter=web...

Run in packages that depend on ui

turbo run build --filter=...^ui

Target specific task in specific package

turbo run web#lint

Source Control Filters

Packages changed since main branch

turbo run build --filter=[main...my-feature]

Packages changed since previous commit

turbo run build --filter=[HEAD^1]

Packages changed between specific commits

turbo run build --filter=[a1b2c3d...e4f5g6h]

Build all packages depending on changes in branch

turbo run build --filter=...[origin/my-feature]

Combine package and source control filters

turbo run build --filter=@acme/ui...[HEAD^1] turbo run test --filter=@acme/{./packages/}[HEAD^1]

Affected Flag (CI Optimized)

Run only on packages with code changes (auto-detects CI environment)

turbo run build --affected

Override comparison branches via environment

TURBO_SCM_BASE=main TURBO_SCM_HEAD=HEAD turbo run build --affected

Workspace Filters

All apps

turbo run build --filter="./apps/*"

All packages

turbo run build --filter="./packages/*"

Exclude specific package

turbo run build --filter=./apps/* --filter=!./apps/admin

Multiple specific packages

turbo run build --filter=docs --filter=web

Package Configuration

Internal Package (packages/ui/package.json)

{ "name": "@repo/ui", "version": "0.0.0", "private": true, "exports": { ".": "./src/index.tsx", "./button": "./src/button.tsx", "./card": "./src/card.tsx" }, "scripts": { "build": "tsup", "lint": "eslint src/", "typecheck": "tsc --noEmit" }, "devDependencies": { "@repo/config": "workspace:*", "typescript": "^5.0.0" } }

App Package (apps/web/package.json)

{ "name": "web", "version": "0.0.0", "private": true, "scripts": { "build": "next build", "dev": "next dev", "lint": "next lint", "start": "next start" }, "dependencies": { "@repo/ui": "workspace:", "@repo/utils": "workspace:", "next": "^16.1.1", "react": "^19.0.0" } }

CI/CD Integration

GitHub Actions

name: CI

on: push: branches: [main] pull_request:

jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 # Full history for --affected flag

  - uses: pnpm/action-setup@v4
    with:
      version: 10

  - uses: actions/setup-node@v4
    with:
      node-version: 22
      cache: 'pnpm'

  - run: pnpm install --frozen-lockfile

  # Option 1: Run all tasks with remote caching
  - run: pnpm turbo run build lint test
    env:
      TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
      TURBO_TEAM: ${{ vars.TURBO_TEAM }}

  # Option 2: Run only affected packages (optimized for large repos)
  - run: pnpm turbo run build lint test --affected
    env:
      TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
      TURBO_TEAM: ${{ vars.TURBO_TEAM }}

Best Practices

  • Keep packages focused - Single responsibility

  • Use workspace protocol - workspace:* for internal deps

  • Share configs - Put ESLint, TS config in packages/config

  • Cache aggressively - Remote caching for CI

  • Filter in CI - Only build what changed

References

  • references/configuration.md - Full config reference

  • references/filters.md - Filter patterns

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

nextjs

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

playwright

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

dapp-integration

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

prisma

No summary provided by upstream source.

Repository SourceNeeds Review