| layout | default |
|---|---|
| title | Chapter 1: Getting Started with Turborepo |
| parent | Turborepo Tutorial |
| nav_order | 1 |
Welcome to Turborepo! If you've ever struggled with slow builds in large monorepos, you're in the right place. Turborepo is the high-performance build system that makes your monorepo feel as fast as a single package, using intelligent caching and parallel execution.
Turborepo revolutionizes monorepo development by:
- Intelligent Caching - Never rebuild unchanged code
- Parallel Execution - Run tasks simultaneously across packages
- Smart Scheduling - Only run tasks when dependencies change
- Remote Caching - Share build artifacts across your team
- Zero Configuration - Works out of the box with sensible defaults
- Framework Agnostic - Supports any JavaScript/TypeScript tool
# Create a new Turborepo
npx create-turbo@latest my-monorepo
cd my-monorepo
# Or add to existing project
npm install turbo --save-dev
# Initialize Turborepo in existing monorepo
npx turbo initmy-monorepo/
├── packages/
│ ├── ui/ # Shared UI components
│ ├── utils/ # Shared utilities
│ └── config/ # Shared configuration
├── apps/
│ ├── web/ # Next.js application
│ └── docs/ # Documentation site
├── package.json
├── turbo.json # Turborepo configuration
└── yarn.lockLet's create a simple monorepo with Turborepo:
// package.json (root)
{
"name": "my-monorepo",
"private": true,
"workspaces": [
"apps/*",
"packages/*"
],
"scripts": {
"build": "turbo run build",
"dev": "turbo run dev",
"lint": "turbo run lint"
},
"devDependencies": {
"turbo": "^1.10.0"
}
}// turbo.json
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": [
"**/.env.*local"
],
"tasks": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**", "!.next/cache/**"]
},
"dev": {
"cache": false,
"persistent": true
},
"lint": {},
"test": {
"dependsOn": ["build"],
"inputs": ["src/**/*.tsx", "src/**/*.ts", "test/**/*.ts", "test/**/*.tsx"]
}
}
}// turbo.json with dependencies
{
"tasks": {
"build": {
"dependsOn": ["^build"], // Wait for dependencies to build first
"outputs": ["dist/**"] // Cache these outputs
},
"test": {
"dependsOn": ["build"], // Must build before testing
"inputs": ["src/**", "test/**"] // Watch these files for changes
},
"lint": {
"dependsOn": [] // No dependencies
}
}
}// packages/ui/package.json
{
"name": "@my-monorepo/ui",
"version": "1.0.0",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"scripts": {
"build": "tsup src/index.ts --format cjs,esm --dts",
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
"lint": "eslint src/**/*.ts",
"test": "jest"
},
"dependencies": {
"react": "^18.2.0"
},
"devDependencies": {
"tsup": "^7.2.0",
"typescript": "^5.2.0"
}
}// apps/web/package.json
{
"name": "@my-monorepo/web",
"version": "1.0.0",
"scripts": {
"build": "next build",
"dev": "next dev",
"lint": "next lint",
"start": "next start"
},
"dependencies": {
"@my-monorepo/ui": "*",
"next": "^14.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}# Run build for all packages
turbo run build
# Run dev for specific packages
turbo run dev --filter=@my-monorepo/web
# Run tests with dependencies
turbo run test --filter=@my-monorepo/ui
# Run lint for all packages
turbo run lint
# Dry run to see what would execute
turbo run build --dry-run# Run only for specific package
turbo run build --filter=@my-monorepo/ui
# Run for package and its dependencies
turbo run build --filter=@my-monorepo/web
# Run for packages matching pattern
turbo run test --filter="./packages/*"
# Exclude specific packages
turbo run lint --filter="!@my-monorepo/docs"# Check cache status
turbo run build --filter=@my-monorepo/ui
# Output shows:
# • Packages in scope: @my-monorepo/ui
# • Running build in 1 packages
# • Remote caching enabled
# Run again (should use cache)
turbo run build --filter=@my-monorepo/ui
# Output shows:
# • Packages in scope: @my-monorepo/ui
# • Running build in 1 packages
# • Remote cache hit: 100% (1/1)// turbo.json with cache configuration
{
"tasks": {
"build": {
"outputs": [
"dist/**",
".next/**",
"!.next/cache/**"
],
"inputs": [
"src/**",
"package.json",
"tsconfig.json"
]
},
"test": {
"inputs": [
"src/**/*.ts",
"test/**/*.ts",
"jest.config.js"
],
"outputs": [
"coverage/**"
]
}
}
}# Build entire monorepo
turbo run build
# Turborepo automatically:
# 1. Analyzes dependencies between packages
# 2. Schedules tasks in optimal order
# 3. Runs independent tasks in parallel
# 4. Caches outputs for future runs
# 5. Handles failures gracefullygraph TD
A[config] --> C[ui]
A --> D[utils]
C --> E[web]
D --> E
C --> F[docs]
D --> F
classDef package fill:#e1f5fe,stroke:#01579b
classDef app fill:#f3e5f5,stroke:#4a148c
class A,C,D package
class E,F app
# Get detailed execution information
turbo run build --log-order=stream
# See dependency graph
turbo run build --graph
# Debug specific package
turbo run build --filter=@my-monorepo/ui --log-level=debug
# Continue after failure
turbo run build --continue# Clear cache if issues occur
turbo run build --force
# Clear all caches
rm -rf node_modules/.cache/turbo
# Check for configuration issues
turbo run build --dry-run --log-level=debug// packages/ui/tsconfig.json
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["dist", "node_modules"]
}// packages/ui/.eslintrc.js
module.exports = {
extends: ['../../.eslintrc.js'],
rules: {
// Package-specific rules
}
}Congratulations! 🎉 You've successfully:
- Installed Turborepo and created your first monorepo
- Configured workspaces with proper package structure
- Set up task pipelines with dependencies and caching
- Executed parallel builds with intelligent scheduling
- Implemented caching for faster subsequent builds
- Debugged pipeline issues and handled errors
- Integrated with development tools like TypeScript and ESLint
Now that you understand Turborepo basics, let's explore workspace configuration in depth. In Chapter 2: Workspace Configuration, we'll dive into advanced workspace setup, package management, and configuration patterns.
Practice what you've learned:
- Create a monorepo with multiple packages
- Set up build pipelines with dependencies
- Experiment with different filtering options
- Implement caching for your tasks
- Debug and optimize your pipeline execution
What's your biggest monorepo performance challenge? ⚡
Most teams struggle here because the hard part is not writing more code, but deciding clear boundaries for turbo, build, monorepo so behavior stays predictable as complexity grows.
In practical terms, this chapter helps you avoid three common failures:
- coupling core logic too tightly to one implementation path
- missing the handoff boundaries between setup, execution, and validation
- shipping changes without clear rollback or observability strategy
After working through this chapter, you should be able to reason about Chapter 1: Getting Started with Turborepo as an operating subsystem inside Turborepo Tutorial: High-Performance Monorepo Build System, with explicit contracts for inputs, state transitions, and outputs.
Use the implementation notes around packages, json, package as your checklist when adapting these patterns to your own repository.
Under the hood, Chapter 1: Getting Started with Turborepo usually follows a repeatable control path:
- Context bootstrap: initialize runtime config and prerequisites for
turbo. - Input normalization: shape incoming data so
buildreceives stable contracts. - Core execution: run the main logic branch and propagate intermediate state through
monorepo. - Policy and safety checks: enforce limits, auth scopes, and failure boundaries.
- Output composition: return canonical result payloads for downstream consumers.
- Operational telemetry: emit logs/metrics needed for debugging and performance tuning.
When debugging, walk this sequence in order and confirm each stage has explicit success/failure conditions.
Use the following upstream sources to verify implementation details while reading this chapter:
- View Repo
Why it matters: authoritative reference on
View Repo(github.com).
Suggested trace strategy:
- search upstream code for
turboandbuildto map concrete implementation paths - compare docs claims against actual runtime/config code before reusing patterns in production