Turborepo: High-Performance Monorepo Build System
Master Turborepo for monorepo management. Learn workspace setup, caching, pipelines, and build performant multi-package JavaScript projects.
Moshiour Rahman
Advertisement
What is Turborepo?
Turborepo is a high-performance build system for JavaScript and TypeScript monorepos. It provides intelligent caching, parallel execution, and incremental builds to dramatically speed up development.
Key Features
| Feature | Description |
|---|---|
| Caching | Local and remote build caching |
| Parallelization | Run tasks concurrently |
| Incremental | Only rebuild what changed |
| Pipelines | Define task dependencies |
Getting Started
Create New Monorepo
# Create new Turborepo
npx create-turbo@latest my-monorepo
# Or with specific package manager
npx create-turbo@latest my-monorepo --package-manager pnpm
Add to Existing Project
# Install Turborepo
npm install turbo --save-dev
# Or globally
npm install turbo --global
Project Structure
my-monorepo/
├── apps/
│ ├── web/
│ │ ├── package.json
│ │ └── ...
│ └── docs/
│ ├── package.json
│ └── ...
├── packages/
│ ├── ui/
│ │ ├── package.json
│ │ └── ...
│ ├── config/
│ │ ├── eslint/
│ │ └── typescript/
│ └── utils/
│ ├── package.json
│ └── ...
├── package.json
├── turbo.json
└── pnpm-workspace.yaml
Configuration
turbo.json
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": ["**/.env.*local"],
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**", "!.next/cache/**"]
},
"lint": {
"dependsOn": ["^lint"]
},
"test": {
"dependsOn": ["build"],
"outputs": ["coverage/**"],
"inputs": ["src/**/*.tsx", "src/**/*.ts", "test/**/*.ts"]
},
"dev": {
"cache": false,
"persistent": true
},
"clean": {
"cache": false
}
}
}
Workspace Configuration
# pnpm-workspace.yaml
packages:
- 'apps/*'
- 'packages/*'
// package.json (npm/yarn workspaces)
{
"workspaces": [
"apps/*",
"packages/*"
]
}
Root package.json
{
"name": "my-monorepo",
"private": true,
"scripts": {
"build": "turbo run build",
"dev": "turbo run dev",
"lint": "turbo run lint",
"test": "turbo run test",
"clean": "turbo run clean && rm -rf node_modules"
},
"devDependencies": {
"turbo": "^1.10.0"
},
"packageManager": "pnpm@8.0.0"
}
Pipeline Configuration
Task Dependencies
{
"pipeline": {
// ^build means run build in dependencies first
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
},
// Run lint after linting dependencies
"lint": {
"dependsOn": ["^lint"]
},
// Run test after build completes
"test": {
"dependsOn": ["build"]
},
// Deploy depends on build and test
"deploy": {
"dependsOn": ["build", "test", "lint"],
"outputs": []
}
}
}
Caching
{
"pipeline": {
"build": {
"dependsOn": ["^build"],
// Files that are outputs
"outputs": ["dist/**", ".next/**"],
// Files that affect cache
"inputs": [
"src/**",
"!src/**/*.test.ts"
]
},
"dev": {
// Never cache dev server
"cache": false,
// Keep running
"persistent": true
}
}
}
Environment Variables
{
"globalEnv": ["CI", "NODE_ENV"],
"pipeline": {
"build": {
"dependsOn": ["^build"],
"env": ["DATABASE_URL", "API_KEY"],
"outputs": ["dist/**"]
},
"test": {
"env": ["TEST_DATABASE_URL"],
"outputs": ["coverage/**"]
}
}
}
Running Tasks
Basic Commands
# Run build in all workspaces
turbo run build
# Run multiple tasks
turbo run build lint test
# Run in specific workspace
turbo run build --filter=web
# Run in workspace and dependencies
turbo run build --filter=web...
# Run in dependents only
turbo run build --filter=...ui
# Run with pattern matching
turbo run build --filter="@myorg/*"
turbo run build --filter="./apps/*"
Filtering
# By package name
turbo run build --filter=@myorg/web
# By directory
turbo run build --filter=./apps/web
# Include dependencies
turbo run build --filter=web...
# Include dependents
turbo run build --filter=...ui
# Changed packages (git)
turbo run build --filter=[HEAD^1]
# Combining filters
turbo run build --filter=...@myorg/ui --filter=@myorg/web
Parallel Execution
# Limit concurrency
turbo run build --concurrency=4
turbo run build --concurrency=50%
# Sequential execution
turbo run build --concurrency=1
# Continue on error
turbo run test --continue
Shared Packages
UI Package
// packages/ui/package.json
{
"name": "@myorg/ui",
"version": "0.0.1",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.js"
},
"./button": {
"import": "./dist/button.mjs",
"require": "./dist/button.js"
}
},
"scripts": {
"build": "tsup src/index.tsx --format cjs,esm --dts",
"dev": "tsup src/index.tsx --format cjs,esm --dts --watch",
"lint": "eslint src/"
},
"peerDependencies": {
"react": "^18.0.0"
}
}
// packages/ui/src/index.tsx
export * from './button';
export * from './card';
export * from './input';
Consuming Shared Packages
// apps/web/package.json
{
"name": "@myorg/web",
"dependencies": {
"@myorg/ui": "workspace:*",
"@myorg/utils": "workspace:*"
}
}
// apps/web/src/app.tsx
import { Button, Card } from '@myorg/ui';
import { formatDate } from '@myorg/utils';
export function App() {
return (
<Card>
<p>Today is {formatDate(new Date())}</p>
<Button>Click me</Button>
</Card>
);
}
Shared Configuration
TypeScript Config
// packages/config/typescript/base.json
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true
}
}
// packages/config/typescript/react.json
{
"extends": "./base.json",
"compilerOptions": {
"jsx": "react-jsx",
"lib": ["DOM", "DOM.Iterable", "ES2020"]
}
}
// apps/web/tsconfig.json
{
"extends": "@myorg/config/typescript/react.json",
"include": ["src"],
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}
ESLint Config
// packages/config/eslint/react.js
module.exports = {
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'prettier'
],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint', 'react'],
settings: {
react: {
version: 'detect'
}
},
rules: {
'react/react-in-jsx-scope': 'off'
}
};
// apps/web/.eslintrc.js
module.exports = {
root: true,
extends: ['@myorg/config/eslint/react']
};
Remote Caching
Vercel Remote Cache
# Login to Vercel
turbo login
# Link to Vercel project
turbo link
# Run with remote cache
turbo run build
Self-Hosted Cache
// turbo.json
{
"remoteCache": {
"signature": true
}
}
# Set remote cache URL
export TURBO_API="https://cache.example.com"
export TURBO_TOKEN="your-token"
export TURBO_TEAM="your-team"
turbo run build
CI/CD Integration
GitHub Actions
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
- uses: pnpm/action-setup@v2
with:
version: 8
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- run: pnpm install
- run: pnpm turbo run build lint test
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
Affected Packages Only
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- run: pnpm install
# Only build changed packages
- run: pnpm turbo run build --filter=[HEAD^1]
Generator
Create Package Generator
# Install generator
turbo gen
// turbo/generators/config.ts
import type { PlopTypes } from '@turbo/gen';
export default function generator(plop: PlopTypes.NodePlopAPI) {
plop.setGenerator('package', {
description: 'Create a new package',
prompts: [
{
type: 'input',
name: 'name',
message: 'Package name'
}
],
actions: [
{
type: 'add',
path: 'packages/{{name}}/package.json',
templateFile: 'templates/package.json.hbs'
},
{
type: 'add',
path: 'packages/{{name}}/src/index.ts',
template: 'export const {{name}} = () => {};'
}
]
});
}
Summary
| Feature | Command |
|---|---|
| Build all | turbo run build |
| Filter | --filter=package-name |
| Parallel | --concurrency=N |
| Remote cache | turbo login && turbo link |
| Generate | turbo gen |
Turborepo provides fast, scalable monorepo tooling for JavaScript and TypeScript projects.
Advertisement
Moshiour Rahman
Software Architect & AI Engineer
Enterprise software architect with deep expertise in financial systems, distributed architecture, and AI-powered applications. Building large-scale systems at Fortune 500 companies. Specializing in LLM orchestration, multi-agent systems, and cloud-native solutions. I share battle-tested patterns from real enterprise projects.
Related Articles
Turborepo Advanced Patterns: Production-Ready Monorepo Architecture in 2025
Master production Turborepo patterns with real-world examples. Migration guide, CI/CD pipelines, remote caching, testing strategies, and framework-specific configs.
JavaScriptReact Hooks Complete Guide: useState to Custom Hooks
Master all React hooks from basics to advanced. Learn useState, useEffect, useContext, useReducer, useMemo, useCallback, and create custom hooks.
JavaScriptGraphQL API Development: Complete Guide with Node.js
Master GraphQL API development from scratch. Learn schema design, resolvers, queries, mutations, subscriptions, and authentication best practices.
Comments
Comments are powered by GitHub Discussions.
Configure Giscus at giscus.app to enable comments.