Configure Turborepo for efficient monorepo builds with local and remote caching. Use when setting up Turborepo, optimizing build pipelines, or implementing distributed caching.
Add this skill
npx mdskills install sickn33/turborepo-cachingComprehensive Turborepo caching guide with excellent templates and practical CI/CD examples
1---2name: turborepo-caching3description: Configure Turborepo for efficient monorepo builds with local and remote caching. Use when setting up Turborepo, optimizing build pipelines, or implementing distributed caching.4---56# Turborepo Caching78Production patterns for Turborepo build optimization.910## Do not use this skill when1112- The task is unrelated to turborepo caching13- You need a different domain or tool outside this scope1415## Instructions1617- Clarify goals, constraints, and required inputs.18- Apply relevant best practices and validate outcomes.19- Provide actionable steps and verification.20- If detailed examples are required, open `resources/implementation-playbook.md`.2122## Use this skill when2324- Setting up new Turborepo projects25- Configuring build pipelines26- Implementing remote caching27- Optimizing CI/CD performance28- Migrating from other monorepo tools29- Debugging cache misses3031## Core Concepts3233### 1. Turborepo Architecture3435```36Workspace Root/37├── apps/38│ ├── web/39│ │ └── package.json40│ └── docs/41│ └── package.json42├── packages/43│ ├── ui/44│ │ └── package.json45│ └── config/46│ └── package.json47├── turbo.json48└── package.json49```5051### 2. Pipeline Concepts5253| Concept | Description |54|---------|-------------|55| **dependsOn** | Tasks that must complete first |56| **cache** | Whether to cache outputs |57| **outputs** | Files to cache |58| **inputs** | Files that affect cache key |59| **persistent** | Long-running tasks (dev servers) |6061## Templates6263### Template 1: turbo.json Configuration6465```json66{67 "$schema": "https://turbo.build/schema.json",68 "globalDependencies": [69 ".env",70 ".env.local"71 ],72 "globalEnv": [73 "NODE_ENV",74 "VERCEL_URL"75 ],76 "pipeline": {77 "build": {78 "dependsOn": ["^build"],79 "outputs": [80 "dist/**",81 ".next/**",82 "!.next/cache/**"83 ],84 "env": [85 "API_URL",86 "NEXT_PUBLIC_*"87 ]88 },89 "test": {90 "dependsOn": ["build"],91 "outputs": ["coverage/**"],92 "inputs": [93 "src/**/*.tsx",94 "src/**/*.ts",95 "test/**/*.ts"96 ]97 },98 "lint": {99 "outputs": [],100 "cache": true101 },102 "typecheck": {103 "dependsOn": ["^build"],104 "outputs": []105 },106 "dev": {107 "cache": false,108 "persistent": true109 },110 "clean": {111 "cache": false112 }113 }114}115```116117### Template 2: Package-Specific Pipeline118119```json120// apps/web/turbo.json121{122 "$schema": "https://turbo.build/schema.json",123 "extends": ["//"],124 "pipeline": {125 "build": {126 "outputs": [".next/**", "!.next/cache/**"],127 "env": [128 "NEXT_PUBLIC_API_URL",129 "NEXT_PUBLIC_ANALYTICS_ID"130 ]131 },132 "test": {133 "outputs": ["coverage/**"],134 "inputs": [135 "src/**",136 "tests/**",137 "jest.config.js"138 ]139 }140 }141}142```143144### Template 3: Remote Caching with Vercel145146```bash147# Login to Vercel148npx turbo login149150# Link to Vercel project151npx turbo link152153# Run with remote cache154turbo build --remote-only155156# CI environment variables157TURBO_TOKEN=your-token158TURBO_TEAM=your-team159```160161```yaml162# .github/workflows/ci.yml163name: CI164165on:166 push:167 branches: [main]168 pull_request:169170env:171 TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}172 TURBO_TEAM: ${{ vars.TURBO_TEAM }}173174jobs:175 build:176 runs-on: ubuntu-latest177 steps:178 - uses: actions/checkout@v4179180 - uses: actions/setup-node@v4181 with:182 node-version: 20183 cache: 'npm'184185 - name: Install dependencies186 run: npm ci187188 - name: Build189 run: npx turbo build --filter='...[origin/main]'190191 - name: Test192 run: npx turbo test --filter='...[origin/main]'193```194195### Template 4: Self-Hosted Remote Cache196197```typescript198// Custom remote cache server (Express)199import express from 'express';200import { createReadStream, createWriteStream } from 'fs';201import { mkdir } from 'fs/promises';202import { join } from 'path';203204const app = express();205const CACHE_DIR = './cache';206207// Get artifact208app.get('/v8/artifacts/:hash', async (req, res) => {209 const { hash } = req.params;210 const team = req.query.teamId || 'default';211 const filePath = join(CACHE_DIR, team, hash);212213 try {214 const stream = createReadStream(filePath);215 stream.pipe(res);216 } catch {217 res.status(404).send('Not found');218 }219});220221// Put artifact222app.put('/v8/artifacts/:hash', async (req, res) => {223 const { hash } = req.params;224 const team = req.query.teamId || 'default';225 const dir = join(CACHE_DIR, team);226 const filePath = join(dir, hash);227228 await mkdir(dir, { recursive: true });229230 const stream = createWriteStream(filePath);231 req.pipe(stream);232233 stream.on('finish', () => {234 res.json({ urls: [`${req.protocol}://${req.get('host')}/v8/artifacts/${hash}`] });235 });236});237238// Check artifact exists239app.head('/v8/artifacts/:hash', async (req, res) => {240 const { hash } = req.params;241 const team = req.query.teamId || 'default';242 const filePath = join(CACHE_DIR, team, hash);243244 try {245 await fs.access(filePath);246 res.status(200).end();247 } catch {248 res.status(404).end();249 }250});251252app.listen(3000);253```254255```json256// turbo.json for self-hosted cache257{258 "remoteCache": {259 "signature": false260 }261}262```263264```bash265# Use self-hosted cache266turbo build --api="http://localhost:3000" --token="my-token" --team="my-team"267```268269### Template 5: Filtering and Scoping270271```bash272# Build specific package273turbo build --filter=@myorg/web274275# Build package and its dependencies276turbo build --filter=@myorg/web...277278# Build package and its dependents279turbo build --filter=...@myorg/ui280281# Build changed packages since main282turbo build --filter='...[origin/main]'283284# Build packages in directory285turbo build --filter='./apps/*'286287# Combine filters288turbo build --filter=@myorg/web --filter=@myorg/docs289290# Exclude package291turbo build --filter='!@myorg/docs'292293# Include dependencies of changed294turbo build --filter='...[HEAD^1]...'295```296297### Template 6: Advanced Pipeline Configuration298299```json300{301 "$schema": "https://turbo.build/schema.json",302 "pipeline": {303 "build": {304 "dependsOn": ["^build"],305 "outputs": ["dist/**"],306 "inputs": [307 "$TURBO_DEFAULT$",308 "!**/*.md",309 "!**/*.test.*"310 ]311 },312 "test": {313 "dependsOn": ["^build"],314 "outputs": ["coverage/**"],315 "inputs": [316 "src/**",317 "tests/**",318 "*.config.*"319 ],320 "env": ["CI", "NODE_ENV"]321 },322 "test:e2e": {323 "dependsOn": ["build"],324 "outputs": [],325 "cache": false326 },327 "deploy": {328 "dependsOn": ["build", "test", "lint"],329 "outputs": [],330 "cache": false331 },332 "db:generate": {333 "cache": false334 },335 "db:push": {336 "cache": false,337 "dependsOn": ["db:generate"]338 },339 "@myorg/web#build": {340 "dependsOn": ["^build", "@myorg/db#db:generate"],341 "outputs": [".next/**"],342 "env": ["NEXT_PUBLIC_*"]343 }344 }345}346```347348### Template 7: Root package.json Setup349350```json351{352 "name": "my-turborepo",353 "private": true,354 "workspaces": [355 "apps/*",356 "packages/*"357 ],358 "scripts": {359 "build": "turbo build",360 "dev": "turbo dev",361 "lint": "turbo lint",362 "test": "turbo test",363 "clean": "turbo clean && rm -rf node_modules",364 "format": "prettier --write \"**/*.{ts,tsx,md}\"",365 "changeset": "changeset",366 "version-packages": "changeset version",367 "release": "turbo build --filter=./packages/* && changeset publish"368 },369 "devDependencies": {370 "turbo": "^1.10.0",371 "prettier": "^3.0.0",372 "@changesets/cli": "^2.26.0"373 },374 "packageManager": "npm@10.0.0"375}376```377378## Debugging Cache379380```bash381# Dry run to see what would run382turbo build --dry-run383384# Verbose output with hashes385turbo build --verbosity=2386387# Show task graph388turbo build --graph389390# Force no cache391turbo build --force392393# Show cache status394turbo build --summarize395396# Debug specific task397TURBO_LOG_VERBOSITY=debug turbo build --filter=@myorg/web398```399400## Best Practices401402### Do's403- **Define explicit inputs** - Avoid cache invalidation404- **Use workspace protocol** - `"@myorg/ui": "workspace:*"`405- **Enable remote caching** - Share across CI and local406- **Filter in CI** - Build only affected packages407- **Cache build outputs** - Not source files408409### Don'ts410- **Don't cache dev servers** - Use `persistent: true`411- **Don't include secrets in env** - Use runtime env vars412- **Don't ignore dependsOn** - Causes race conditions413- **Don't over-filter** - May miss dependencies414415## Resources416417- [Turborepo Documentation](https://turbo.build/repo/docs)418- [Caching Guide](https://turbo.build/repo/docs/core-concepts/caching)419- [Remote Caching](https://turbo.build/repo/docs/core-concepts/remote-caching)420
Full transparency — inspect the skill content before installing.