Turborepo Caching
SkillAI & modelsTurborepo-caching is a skill that guides an AI agent through configuring Turborepo for efficient monorepo builds with local and remote caching. It is useful when setting up Turborepo, optimizing build pipelines, or implementing distributed caching, so the agent can produce working cache configuration instead of guesswork.
Use Turborepo Caching in Claude, ChatGPT or Ahel Desktop
Free. Sign in, add Turborepo Caching and connect your AI. About a minute.
Also: Claude Code · Cursor · Codex
Then ask your AI: use the Turborepo Caching skill
Details
Instructions available. Your AI can read the instructions. Execution depends on the setup they require.
Account requirements not reviewed. Check the skill instructions before use; ahel provides instructions and does not run this skill.
No other account needed.
Have a monorepo where Turborepo can be used for builds.
What your AI can do with it
- Set up Turborepo in a monorepo
- Configure local caching for faster rebuilds
- Configure remote caching for shared build artifacts
- Optimize build pipelines across packages
- Implement distributed caching for teams
Getting started
- Have a monorepo where Turborepo can be used for builds.
- Add the turborepo-caching skill to the agent's available skills.
- Ask the agent to set up Turborepo or optimize the build pipelines, and it will apply the skill's caching guidance.
What this skill tells your AI
The instructions your AI receives, as published by wshobson/agents in plugins/developer-essentials/skills/turborepo-caching/SKILL.md and read by ahel’s review.
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
Signals
- GitHub stars
- 40k
- Forks
- 4k
- Last commit
- Sep 2026
Questions
- When should this skill be used?
- When setting up Turborepo, optimizing build pipelines, or implementing distributed caching in a monorepo.
- What kinds of caching does it cover?
- Both local caching on the machine doing the build and remote caching, which lets build artifacts be shared across environments.
Advanced
- Item type
- skill
- Key
turborepo-caching- Source
- github.com/wshobson/agents
More in AI & models
Skill · anthropics
More in AI & modelswayfinder
Skill · mattpocock
More in AI & modelswizard
Skill · mattpocock
More in AI & modelsalgorithmic-art
Skill · anthropics
More in AI & modelscode-review-and-quality
Skill · addyosmani
More in AI & modelsai-first-engineering
Skill · affaan-m
More in AI & models