| 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. |
| risk | critical |
| source | community |
| date_added | 2026-02-27 |
Turborepo Caching
Production patterns for Turborepo build optimization.
Do not use this skill when
- The task is unrelated to turborepo caching
- You need a different domain or tool outside this scope
Instructions
- Clarify goals, constraints, and required inputs.
- Apply relevant best practices and validate outcomes.
- Provide actionable steps and verification.
- If detailed examples are required, open
resources/implementation-playbook.md.
Use this skill when
- 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"
Template 2: Package-Specific Pipeline
{
"$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
npx turbo login
npx turbo link
turbo build --remote-only
TURBO_TOKEN=your-token
TURBO_TEAM=your-team
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
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';
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');
}
});
app.put('/v8/artifacts/:hash', async (req, res) => {
const { hash } = req.params;
const team = req.query.teamId || ;
dir = (, team);
filePath = (dir, hash);
(dir, { : });
stream = (filePath);
req.(stream);
stream.(, {
res.({ : [] });
});
});
app.(, (req, res) => {
{ hash } = req.;
team = req.. || ;
filePath = (, team, hash);
{
fs.(filePath);
res.().();
} {
res.().();
}
});
app.();
{
"remoteCache": {
"signature": false
}
}
turbo build --api="http://localhost:3000" --token="my-token" --team="my-team"
Template 5: Filtering and Scoping
turbo build --filter=@myorg/web
turbo build --filter=@myorg/web...
turbo build --filter=...@myorg/ui
turbo build --filter='...[origin/main]'
turbo build --filter='./apps/*'
turbo build --filter=@myorg/web --filter=@myorg/docs
turbo build --filter='!@myorg/docs'
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.*"
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"
Debugging Cache
turbo build --dry-run
turbo build --verbosity=2
turbo build --graph
turbo build --force
turbo build --summarize
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
Resources
Limitations
- Use this skill only when the task clearly matches the scope described above.
- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.