turborepo-caching
wshobson/agents
Configure Turborepo for efficient monorepo builds with local and remote caching.
What is turborepo-caching?
This skill sets up Turborepo build optimization for monorepos, covering pipeline configuration, local and remote caching strategies, and CI/CD integration. Use it when establishing new Turborepo projects, optimizing build performance, or implementing distributed caching across teams.
- Configure turbo.json pipeline with task dependencies, outputs, and cache settings
- Set up remote caching with Vercel or self-hosted cache servers
- Implement package filtering and scoping for targeted builds in CI/CD
- Define workspace-specific pipeline overrides for individual apps and packages
- Debug cache behavior with dry-run, verbose output, and task graph visualization
- Manage global dependencies and environment variables across the monorepo
How to install turborepo-caching
npx skills add https://github.com/wshobson/agents --skill turborepo-caching- Node.js and npm (or yarn/pnpm) installed
- Existing monorepo structure or willingness to set one up
- For remote caching: Vercel account or self-hosted server infrastructure
How to use turborepo-caching
- 1.Create or update turbo.json at the monorepo root with pipeline task definitions
- 2.Define dependsOn relationships to establish task execution order
- 3.Specify outputs and inputs for each task to control cache keys
- 4.For remote caching, run npx turbo login and npx turbo link to connect to Vercel
- 5.Set TURBO_TOKEN and TURBO_TEAM environment variables in CI/CD workflows
- 6.Use turbo build --filter flags to scope builds to affected packages in pull requests
- 7.Run turbo build --dry-run and turbo build --verbosity=2 to debug cache behavior
Use cases
- Setting up a new monorepo with Turborepo and configuring build pipelines
- Optimizing CI/CD performance by caching only affected packages since main branch
- Implementing team-wide remote caching via Vercel or a self-hosted cache server
- Migrating from other monorepo tools and establishing consistent task dependencies
- Debugging cache misses and task execution order in complex dependency graphs
- Monorepo maintainers and DevOps engineers
- Full-stack teams managing multiple apps and shared packages
- CI/CD pipeline architects optimizing build times
- Teams adopting Turborepo for the first time
turborepo-caching FAQ
Local caching stores build artifacts on your machine; remote caching shares artifacts across team members and CI runners via Vercel or a self-hosted server, reducing redundant builds.
Define explicit inputs in turbo.json for each task (e.g., src/**, tests/**, *.config.*) and exclude files like markdown or test files that don't affect output.
No. Set persistent: true and cache: false for dev tasks to allow hot reloading and prevent stale artifacts.
Use turbo build --filter='...[origin/main]' to build packages changed since the main branch and their dependents.
Yes. Implement a custom Express server with GET/PUT/HEAD endpoints for /v8/artifacts/:hash and configure it with turbo build --api=<url> --token=<token>.
Full instructions (SKILL.md)
Source of truth, from wshobson/agents.
name: turborepo-caching description: Configure Turborepo for efficient monorepo builds with local and remote caching. Use when setting up Turborepo, optimizing build pipelines, or implementing distributed caching.
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
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": [".env", ".env.local"],
"globalEnv": ["NODE_ENV", "VERCEL_URL"],
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", ".next/**", "!.next/cache/**"],
"env": ["API_URL", "NEXT_PUBLIC_*"]
},
"test": {
"dependsOn": ["build"],
"outputs": ["coverage/**"],
"inputs": ["src/**/*.tsx", "src/**/*.ts", "test/**/*.ts"]
},
"lint": {
"outputs": [],
"cache": true
},
"typecheck": {
"dependsOn": ["^build"],
"outputs": []
},
"dev": {
"cache": false,
"persistent": true
},
"clean": {
"cache": false
}
}
}
Template 2: Package-Specific Pipeline
// apps/web/turbo.json
{
"$schema": "https://turbo.build/schema.json",
"extends": ["//"],
"pipeline": {
"build": {
"outputs": [".next/**", "!.next/cache/**"],
"env": ["NEXT_PUBLIC_API_URL", "NEXT_PUBLIC_ANALYTICS_ID"]
},
"test": {
"outputs": ["coverage/**"],
"inputs": ["src/**", "tests/**", "jest.config.js"]
}
}
}
Template 3: Remote Caching with Vercel
# Login to Vercel
npx turbo login
# Link to Vercel project
npx turbo link
# Run with remote cache
turbo build --remote-only
# CI environment variables
TURBO_TOKEN=your-token
TURBO_TEAM=your-team
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Build
run: npx turbo build --filter='...[origin/main]'
- name: Test
run: npx turbo test --filter='...[origin/main]'
Template 4: Self-Hosted Remote Cache
// Custom remote cache server (Express)
import express from "express";
import { createReadStream, createWriteStream } from "fs";
import { mkdir } from "fs/promises";
import { join } from "path";
const app = express();
const CACHE_DIR = "./cache";
// Get artifact
app.get("/v8/artifacts/:hash", async (req, res) => {
const { hash } = req.params;
const team = req.query.teamId || "default";
const filePath = join(CACHE_DIR, team, hash);
try {
const stream = createReadStream(filePath);
stream.pipe(res);
} catch {
res.status(404).send("Not found");
}
});
// Put artifact
app.put("/v8/artifacts/:hash", async (req, res) => {
const { hash } = req.params;
const team = req.query.teamId || "default";
const dir = join(CACHE_DIR, team);
const filePath = join(dir, hash);
await mkdir(dir, { recursive: true });
const stream = createWriteStream(filePath);
req.pipe(stream);
stream.on("finish", () => {
res.json({
urls: [`${req.protocol}://${req.get("host")}/v8/artifacts/${hash}`],
});
});
});
// Check artifact exists
app.head("/v8/artifacts/:hash", async (req, res) => {
const { hash } = req.params;
const team = req.query.teamId || "default";
const filePath = join(CACHE_DIR, team, hash);
try {
await fs.access(filePath);
res.status(200).end();
} catch {
res.status(404).end();
}
});
app.listen(3000);
// turbo.json for self-hosted cache
{
"remoteCache": {
"signature": false
}
}
# Use self-hosted cache
turbo build --api="http://localhost:3000" --token="my-token" --team="my-team"
Template 5: Filtering and Scoping
# Build specific package
turbo build --filter=@myorg/web
# Build package and its dependencies
turbo build --filter=@myorg/web...
# Build package and its dependents
turbo build --filter=...@myorg/ui
# Build changed packages since main
turbo build --filter='...[origin/main]'
# Build packages in directory
turbo build --filter='./apps/*'
# Combine filters
turbo build --filter=@myorg/web --filter=@myorg/docs
# Exclude package
turbo build --filter='!@myorg/docs'
# Include dependencies of changed
turbo build --filter='...[HEAD^1]...'
Template 6: Advanced Pipeline Configuration
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"],
"inputs": ["$TURBO_DEFAULT$", "!**/*.md", "!**/*.test.*"]
},
"test": {
"dependsOn": ["^build"],
"outputs": ["coverage/**"],
"inputs": ["src/**", "tests/**", "*.config.*"],
"env": ["CI", "NODE_ENV"]
},
"test:e2e": {
"dependsOn": ["build"],
"outputs": [],
"cache": false
},
"deploy": {
"dependsOn": ["build", "test", "lint"],
"outputs": [],
"cache": false
},
"db:generate": {
"cache": false
},
"db:push": {
"cache": false,
"dependsOn": ["db:generate"]
},
"@myorg/web#build": {
"dependsOn": ["^build", "@myorg/db#db:generate"],
"outputs": [".next/**"],
"env": ["NEXT_PUBLIC_*"]
}
}
}
Template 7: Root package.json Setup
{
"name": "my-turborepo",
"private": true,
"workspaces": ["apps/*", "packages/*"],
"scripts": {
"build": "turbo build",
"dev": "turbo dev",
"lint": "turbo lint",
"test": "turbo test",
"clean": "turbo clean && rm -rf node_modules",
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
"changeset": "changeset",
"version-packages": "changeset version",
"release": "turbo build --filter=./packages/* && changeset publish"
},
"devDependencies": {
"turbo": "^1.10.0",
"prettier": "^3.0.0",
"@changesets/cli": "^2.26.0"
},
"packageManager": "npm@10.0.0"
}
Debugging Cache
# Dry run to see what would run
turbo build --dry-run
# Verbose output with hashes
turbo build --verbosity=2
# Show task graph
turbo build --graph
# Force no cache
turbo build --force
# Show cache status
turbo build --summarize
# Debug specific task
TURBO_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
Related skills
More from wshobson/agents and the wider catalog.

typescript-advanced-types
Master TypeScript's advanced type system: generics, conditional types, mapped types, and utility types for type-safe applications.

unity-ecs-patterns
Reference patterns and best practices for high-performance Unity DOTS, ECS, Jobs, and Burst development.

uv-package-manager
Ultra-fast Python package manager and virtual environment tool—10-100x faster than pip with built-in dependency resolution and Python version management.

vector-index-tuning
Optimize vector index performance—tune HNSW parameters, quantization, and memory for production scale.

vision-sft
Fine-tune vision-language models with LoRA on frozen vision towers for domain adaptation.

visual-design-foundations
Apply typography, color theory, spacing, and iconography principles to create cohesive visual designs.