Turborepo Caching
Optimize monorepo builds with Turborepo caching strategies
✨ The solution you've been looking for
Configure Turborepo for efficient monorepo builds with local and remote caching. Use when setting up Turborepo, optimizing build pipelines, or implementing distributed caching.
See It In Action
Interactive preview & real-world examples
AI Conversation Simulator
See how users interact with this skill
User Prompt
Help me set up Turborepo for a new monorepo with React apps and shared packages
Skill Processing
Analyzing request...
Agent Response
Complete turbo.json configuration with pipeline definitions, caching rules, and workspace structure
Quick Start (3 Steps)
Get up and running in minutes
Install
claude-code skill install turborepo-caching
claude-code skill install turborepo-cachingConfig
First Trigger
@turborepo-caching helpCommands
| Command | Description | Required Args |
|---|---|---|
| @turborepo-caching new-turborepo-setup | Configure a fresh monorepo with optimal caching from the start | None |
| @turborepo-caching ci/cd-optimization | Implement remote caching to speed up continuous integration builds | None |
| @turborepo-caching cache-performance-debugging | Identify and resolve cache misses and build performance issues | None |
Typical Use Cases
New Turborepo Setup
Configure a fresh monorepo with optimal caching from the start
CI/CD Optimization
Implement remote caching to speed up continuous integration builds
Cache Performance Debugging
Identify and resolve cache misses and build performance issues
Overview
Turborepo Caching
Production patterns for Turborepo build optimization.
When to Use This Skill
- Setting up new Turborepo projects
- Configuring build pipelines
- Implementing remote caching
- Optimizing CI/CD performance
- Migrating from other monorepo tools
- Debugging cache misses
Core Concepts
1. Turborepo Architecture
Workspace Root/
├── apps/
│ ├── web/
│ │ └── package.json
│ └── docs/
│ └── package.json
├── packages/
│ ├── ui/
│ │ └── package.json
│ └── config/
│ └── package.json
├── turbo.json
└── package.json
2. Pipeline Concepts
| Concept | Description |
|---|---|
| dependsOn | Tasks that must complete first |
| cache | Whether to cache outputs |
| outputs | Files to cache |
| inputs | Files that affect cache key |
| persistent | Long-running tasks (dev servers) |
Templates
Template 1: turbo.json Configuration
1{
2 "$schema": "https://turbo.build/schema.json",
3 "globalDependencies": [".env", ".env.local"],
4 "globalEnv": ["NODE_ENV", "VERCEL_URL"],
5 "pipeline": {
6 "build": {
7 "dependsOn": ["^build"],
8 "outputs": ["dist/**", ".next/**", "!.next/cache/**"],
9 "env": ["API_URL", "NEXT_PUBLIC_*"]
10 },
11 "test": {
12 "dependsOn": ["build"],
13 "outputs": ["coverage/**"],
14 "inputs": ["src/**/*.tsx", "src/**/*.ts", "test/**/*.ts"]
15 },
16 "lint": {
17 "outputs": [],
18 "cache": true
19 },
20 "typecheck": {
21 "dependsOn": ["^build"],
22 "outputs": []
23 },
24 "dev": {
25 "cache": false,
26 "persistent": true
27 },
28 "clean": {
29 "cache": false
30 }
31 }
32}
Template 2: Package-Specific Pipeline
1// apps/web/turbo.json
2{
3 "$schema": "https://turbo.build/schema.json",
4 "extends": ["//"],
5 "pipeline": {
6 "build": {
7 "outputs": [".next/**", "!.next/cache/**"],
8 "env": ["NEXT_PUBLIC_API_URL", "NEXT_PUBLIC_ANALYTICS_ID"]
9 },
10 "test": {
11 "outputs": ["coverage/**"],
12 "inputs": ["src/**", "tests/**", "jest.config.js"]
13 }
14 }
15}
Template 3: Remote Caching with Vercel
1# Login to Vercel
2npx turbo login
3
4# Link to Vercel project
5npx turbo link
6
7# Run with remote cache
8turbo build --remote-only
9
10# CI environment variables
11TURBO_TOKEN=your-token
12TURBO_TEAM=your-team
1# .github/workflows/ci.yml
2name: CI
3
4on:
5 push:
6 branches: [main]
7 pull_request:
8
9env:
10 TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
11 TURBO_TEAM: ${{ vars.TURBO_TEAM }}
12
13jobs:
14 build:
15 runs-on: ubuntu-latest
16 steps:
17 - uses: actions/checkout@v4
18
19 - uses: actions/setup-node@v4
20 with:
21 node-version: 20
22 cache: "npm"
23
24 - name: Install dependencies
25 run: npm ci
26
27 - name: Build
28 run: npx turbo build --filter='...[origin/main]'
29
30 - name: Test
31 run: npx turbo test --filter='...[origin/main]'
Template 4: Self-Hosted Remote Cache
1// Custom remote cache server (Express)
2import express from "express";
3import { createReadStream, createWriteStream } from "fs";
4import { mkdir } from "fs/promises";
5import { join } from "path";
6
7const app = express();
8const CACHE_DIR = "./cache";
9
10// Get artifact
11app.get("/v8/artifacts/:hash", async (req, res) => {
12 const { hash } = req.params;
13 const team = req.query.teamId || "default";
14 const filePath = join(CACHE_DIR, team, hash);
15
16 try {
17 const stream = createReadStream(filePath);
18 stream.pipe(res);
19 } catch {
20 res.status(404).send("Not found");
21 }
22});
23
24// Put artifact
25app.put("/v8/artifacts/:hash", async (req, res) => {
26 const { hash } = req.params;
27 const team = req.query.teamId || "default";
28 const dir = join(CACHE_DIR, team);
29 const filePath = join(dir, hash);
30
31 await mkdir(dir, { recursive: true });
32
33 const stream = createWriteStream(filePath);
34 req.pipe(stream);
35
36 stream.on("finish", () => {
37 res.json({
38 urls: [`${req.protocol}://${req.get("host")}/v8/artifacts/${hash}`],
39 });
40 });
41});
42
43// Check artifact exists
44app.head("/v8/artifacts/:hash", async (req, res) => {
45 const { hash } = req.params;
46 const team = req.query.teamId || "default";
47 const filePath = join(CACHE_DIR, team, hash);
48
49 try {
50 await fs.access(filePath);
51 res.status(200).end();
52 } catch {
53 res.status(404).end();
54 }
55});
56
57app.listen(3000);
1// turbo.json for self-hosted cache
2{
3 "remoteCache": {
4 "signature": false
5 }
6}
1# Use self-hosted cache
2turbo build --api="http://localhost:3000" --token="my-token" --team="my-team"
Template 5: Filtering and Scoping
1# Build specific package
2turbo build --filter=@myorg/web
3
4# Build package and its dependencies
5turbo build --filter=@myorg/web...
6
7# Build package and its dependents
8turbo build --filter=...@myorg/ui
9
10# Build changed packages since main
11turbo build --filter='...[origin/main]'
12
13# Build packages in directory
14turbo build --filter='./apps/*'
15
16# Combine filters
17turbo build --filter=@myorg/web --filter=@myorg/docs
18
19# Exclude package
20turbo build --filter='!@myorg/docs'
21
22# Include dependencies of changed
23turbo build --filter='...[HEAD^1]...'
Template 6: Advanced Pipeline Configuration
1{
2 "$schema": "https://turbo.build/schema.json",
3 "pipeline": {
4 "build": {
5 "dependsOn": ["^build"],
6 "outputs": ["dist/**"],
7 "inputs": ["$TURBO_DEFAULT$", "!**/*.md", "!**/*.test.*"]
8 },
9 "test": {
10 "dependsOn": ["^build"],
11 "outputs": ["coverage/**"],
12 "inputs": ["src/**", "tests/**", "*.config.*"],
13 "env": ["CI", "NODE_ENV"]
14 },
15 "test:e2e": {
16 "dependsOn": ["build"],
17 "outputs": [],
18 "cache": false
19 },
20 "deploy": {
21 "dependsOn": ["build", "test", "lint"],
22 "outputs": [],
23 "cache": false
24 },
25 "db:generate": {
26 "cache": false
27 },
28 "db:push": {
29 "cache": false,
30 "dependsOn": ["db:generate"]
31 },
32 "@myorg/web#build": {
33 "dependsOn": ["^build", "@myorg/db#db:generate"],
34 "outputs": [".next/**"],
35 "env": ["NEXT_PUBLIC_*"]
36 }
37 }
38}
Template 7: Root package.json Setup
1{
2 "name": "my-turborepo",
3 "private": true,
4 "workspaces": ["apps/*", "packages/*"],
5 "scripts": {
6 "build": "turbo build",
7 "dev": "turbo dev",
8 "lint": "turbo lint",
9 "test": "turbo test",
10 "clean": "turbo clean && rm -rf node_modules",
11 "format": "prettier --write \"**/*.{ts,tsx,md}\"",
12 "changeset": "changeset",
13 "version-packages": "changeset version",
14 "release": "turbo build --filter=./packages/* && changeset publish"
15 },
16 "devDependencies": {
17 "turbo": "^1.10.0",
18 "prettier": "^3.0.0",
19 "@changesets/cli": "^2.26.0"
20 },
21 "packageManager": "npm@10.0.0"
22}
Debugging Cache
1# Dry run to see what would run
2turbo build --dry-run
3
4# Verbose output with hashes
5turbo build --verbosity=2
6
7# Show task graph
8turbo build --graph
9
10# Force no cache
11turbo build --force
12
13# Show cache status
14turbo build --summarize
15
16# Debug specific task
17TURBO_LOG_VERBOSITY=debug turbo build --filter=@myorg/web
Best Practices
Do’s
- Define explicit inputs - Avoid cache invalidation
- Use workspace protocol -
"@myorg/ui": "workspace:*" - Enable remote caching - Share across CI and local
- Filter in CI - Build only affected packages
- Cache build outputs - Not source files
Don’ts
- Don’t cache dev servers - Use
persistent: true - Don’t include secrets in env - Use runtime env vars
- Don’t ignore dependsOn - Causes race conditions
- Don’t over-filter - May miss dependencies
Resources
What Users Are Saying
Real feedback from the community
Environment Matrix
Dependencies
Framework Support
Context Window
Security & Privacy
Information
- Author
- wshobson
- Updated
- 2026-01-30
- Category
- automation-tools
Related Skills
Turborepo Caching
Configure Turborepo for efficient monorepo builds with local and remote caching. Use when setting up …
View Details →Monorepo Management
Master monorepo management with Turborepo, Nx, and pnpm workspaces to build efficient, scalable …
View Details →Monorepo Management
Master monorepo management with Turborepo, Nx, and pnpm workspaces to build efficient, scalable …
View Details →