DEV Community

Alex Spinov
Alex Spinov

Posted on

Turborepo Has a Free Monorepo Build System That Never Rebuilds Twice

Your monorepo CI takes 45 minutes because it rebuilds everything. Turborepo caches build outputs and only rebuilds what changed — cutting CI time by 40-80%.

The Problem

monorepo/
  apps/web/         ← Changed 1 file
  apps/api/         ← Unchanged
  packages/ui/      ← Unchanged
  packages/config/  ← Unchanged
Enter fullscreen mode Exit fullscreen mode

Traditional CI: Rebuild ALL 4 packages. Time: 15 minutes.
Turborepo: Rebuild ONLY web (cache the rest). Time: 3 minutes.

Setup

npx create-turbo@latest my-monorepo
# Or add to existing monorepo:
npm install turbo --save-dev
Enter fullscreen mode Exit fullscreen mode
// turbo.json
{
  "$schema": "https://turbo.build/schema.json",
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**", ".next/**"]
    },
    "test": {
      "dependsOn": ["build"]
    },
    "lint": {},
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Key Concepts

Task Graph

"build": {
  "dependsOn": ["^build"]
}
Enter fullscreen mode Exit fullscreen mode

^build means: before building a package, build all its dependencies first. Turborepo figures out the order automatically.

Caching

turbo build
# First run: builds everything, caches outputs
# Second run: "cache hit, replaying output" — instant
Enter fullscreen mode Exit fullscreen mode

Turborepo hashes: source files, dependencies, env vars, config. If nothing changed → replay from cache.

Remote Caching

# Login to Vercel (free remote cache)
npx turbo login
npx turbo link

# Now CI and all developers share the cache
# Developer A builds → pushes cache → Developer B gets instant build
Enter fullscreen mode Exit fullscreen mode

Parallel Execution

turbo build lint test
# Runs independent tasks in parallel
# Respects dependencies (test waits for build)
Enter fullscreen mode Exit fullscreen mode

Workspace Structure

monorepo/
  apps/
    web/          ← Next.js app
    api/          ← Express API
    mobile/       ← React Native
  packages/
    ui/           ← Shared components
    config/       ← Shared ESLint/TS configs
    database/     ← Prisma schema & client
    utils/        ← Shared utilities
  turbo.json
  package.json
Enter fullscreen mode Exit fullscreen mode
// Root package.json
{
  "workspaces": ["apps/*", "packages/*"]
}
Enter fullscreen mode Exit fullscreen mode

Filtering

# Build only the web app and its dependencies
turbo build --filter=web

# Build everything that changed since main
turbo build --filter=...[main...HEAD]

# Run tests only for packages that depend on @repo/ui
turbo test --filter=...@repo/ui
Enter fullscreen mode Exit fullscreen mode

CI Performance

Without Turborepo With Turborepo
Full build 15 min 15 min (first) / 3 min (cached)
Single package change 15 min 2-4 min
Lint + Test + Build 25 min 5-8 min
PR checks 20 min 3-5 min

Need monorepo architecture help? I build developer tools and infrastructure. Email spinov001@gmail.com or check my Apify tools.

Top comments (0)