Turborepo Caching
Seth HobsonCommunityCreated by Seth Hobson
- Skill
- Tool integration
- Software development
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides patterns and configuration templates for managing Turborepo build pipelines. It covers the setup of local and remote caching, pipeline dependency management, workspace filtering, and integration with CI/CD environments. It includes guidance on defining task inputs and outputs to ensure accurate cache behavior across development and production environments.
What it does
- Defines pipeline task dependencies and caching rules in turbo.json
- Configures remote caching for shared build artifacts
- Implements workspace filtering to target specific packages or changed code
- Provides patterns for CI/CD pipeline integration
- Offers methods for debugging cache misses and task execution
- Demonstrates custom remote cache server implementation
When to use it
- Setting up a new monorepo project using Turborepo
- Optimizing build pipelines for faster execution
- Implementing distributed caching across team members and CI
- Migrating existing monorepo structures
- Troubleshooting unexpected cache behavior
Advantages
- Reduces redundant work by caching build outputs
- Enables shared build artifacts between local and remote environments
- Allows granular control over task dependencies and inputs
- Supports targeted builds through package filtering
Usage examples
- “How do I configure my turbo.json to cache build outputs but not dev servers?”
- The skill provides a template showing how to set 'cache: true' for build tasks and 'cache: false' with 'persistent: true' for dev tasks.
- “How can I build only the packages that changed since the main branch?”
- The skill demonstrates using the --filter='...[origin/main]' flag to scope builds to affected packages.
- “How do I set up remote caching in my CI pipeline?”
- The skill provides a GitHub Actions workflow example using TURBO_TOKEN and TURBO_TEAM environment variables.
- “How do I debug why a task is not being cached?”
- The skill lists commands like --dry-run, --verbosity=2, and --summarize to inspect task execution and cache status.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/wshobson/turborepo-caching/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip turborepo-caching.zip -d .agents/skills
Documentation by Seth Hobson
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.json2. 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, "127.0.0.1");// turbo.json for the local cache demo
{
"remoteCache": {
"signature": false
}
}# This local demo does not authenticate the dummy token.
# Use only disposable artifacts on a trusted machine; do not expose the server.
turbo build --api="http://127.0.0.1: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": "[email protected]"
}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/webBest 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: trueDon't include secrets in env - Use runtime env vars
Don't ignore dependsOn - Causes race conditions
Don't over-filter - May miss dependencies
Files
- ATTRIBUTION.mdAdded by AutoGineer991 B
- LICENSELicence file added by AutoGineer1.0 KiB
- SKILL.md8.0 KiB
ATTRIBUTION.md
Attribution
This folder is an unmodified copy of the Agent Skill "turborepo-caching", distributed by AutoGineer (https://autogineer.com/agent-skills).
Commit: 4bde3168b43c0655c4d00ea2726e631719908a6d
Created by: Seth Hobson (https://github.com/wshobson/agents/tree/4bde3168b43c0655c4d00ea2726e631719908a6d/plugins/developer-essentials/skills/turborepo-caching)
Publisher: Seth Hobson (https://github.com/wshobson)
Licence: MIT License (https://github.com/wshobson/agents/blob/4bde3168b43c0655c4d00ea2726e631719908a6d/LICENSE)
Licence evidence: repository licence LICENSE
Retrieved: 2026-11-07
The skill's own files are unmodified copies. AutoGineer is not affiliated with or endorsed by the author or the publisher.
Files added by AutoGineer
ATTRIBUTION.md: this file, written by AutoGineer
LICENSE: copied from LICENSE
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs Node.js
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- Seth Hobson
- Publisher
- Seth Hobson (Community)
- Source
- wshobson/agents · plugins/developer-essentials/skills/turborepo-caching · commit 4bde316
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Seth Hobson or Seth Hobson.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download turborepo-caching.zip