{
  "schemaVersion": "1.0",
  "item": {
    "slug": "turborepo",
    "name": "Turborepo",
    "source": "tencent",
    "type": "skill",
    "category": "效率提升",
    "sourceUrl": "https://clawhub.ai/wpank/turborepo",
    "canonicalUrl": "https://clawhub.ai/wpank/turborepo",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/turborepo",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=turborepo",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "README.md",
      "SKILL.md",
      "command/turborepo.md",
      "references/best-practices/structure.md",
      "references/best-practices/dependencies.md",
      "references/best-practices/packages.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/turborepo"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/turborepo",
    "agentPageUrl": "https://openagent3.xyz/skills/turborepo/agent",
    "manifestUrl": "https://openagent3.xyz/skills/turborepo/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/turborepo/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Turborepo",
        "body": "Build system for JavaScript/TypeScript monorepos. Caches task outputs and runs tasks in parallel based on dependency graph."
      },
      {
        "title": "OpenClaw / Moltbot / Clawbot",
        "body": "npx clawhub@latest install turborepo"
      },
      {
        "title": "NEVER",
        "body": "NEVER create root tasks - Always create package-level tasks in each package's package.json\nNEVER use turbo <task> shorthand in code - Use turbo run <task> in package.json and CI\nNEVER bypass turbo - Root scripts must delegate via turbo run, not run tasks directly\nNEVER chain turbo tasks with && - Let turbo orchestrate dependencies via dependsOn\nNEVER use --parallel flag - Configure dependsOn correctly instead\nNEVER put .env at repo root - Use package-level .env files for clarity\nNEVER use ../ in inputs - Use $TURBO_ROOT$/path for repo root files"
      },
      {
        "title": "IMPORTANT: Package Tasks, Not Root Tasks",
        "body": "DO NOT create Root Tasks. ALWAYS create package tasks.\n\nWhen creating tasks/scripts/pipelines, you MUST:\n\nAdd the script to each relevant package's package.json\nRegister the task in root turbo.json\nRoot package.json only delegates via turbo run <task>\n\nDO NOT put task logic in root package.json. This defeats Turborepo's parallelization.\n\n// DO THIS: Scripts in each package\n// apps/web/package.json\n{ \"scripts\": { \"build\": \"next build\", \"lint\": \"eslint .\", \"test\": \"vitest\" } }\n\n// apps/api/package.json\n{ \"scripts\": { \"build\": \"tsc\", \"lint\": \"eslint .\", \"test\": \"vitest\" } }\n\n// packages/ui/package.json\n{ \"scripts\": { \"build\": \"tsc\", \"lint\": \"eslint .\", \"test\": \"vitest\" } }\n\n// turbo.json - register tasks\n{\n  \"tasks\": {\n    \"build\": { \"dependsOn\": [\"^build\"], \"outputs\": [\"dist/**\"] },\n    \"lint\": {},\n    \"test\": { \"dependsOn\": [\"build\"] }\n  }\n}\n\n// Root package.json - ONLY delegates, no task logic\n{\n  \"scripts\": {\n    \"build\": \"turbo run build\",\n    \"lint\": \"turbo run lint\",\n    \"test\": \"turbo run test\"\n  }\n}\n\n// DO NOT DO THIS - defeats parallelization\n// Root package.json\n{\n  \"scripts\": {\n    \"build\": \"cd apps/web && next build && cd ../api && tsc\",\n    \"lint\": \"eslint apps/ packages/\",\n    \"test\": \"vitest\"\n  }\n}\n\nRoot Tasks (//#taskname) are ONLY for tasks that truly cannot exist in packages (rare)."
      },
      {
        "title": "Secondary Rule: turbo run vs turbo",
        "body": "Always use turbo run when the command is written into code:\n\n// package.json - ALWAYS \"turbo run\"\n{\n  \"scripts\": {\n    \"build\": \"turbo run build\"\n  }\n}\n\n# CI workflows - ALWAYS \"turbo run\"\n- run: turbo run build --affected\n\nThe shorthand turbo <tasks> is ONLY for one-off terminal commands typed directly by humans or agents. Never write turbo build into package.json, CI, or scripts."
      },
      {
        "title": "\"I need to configure a task\"",
        "body": "Configure a task?\n├─ Define task dependencies → references/configuration/tasks.md\n├─ Lint/check-types (parallel + caching) → Use Transit Nodes pattern (see below)\n├─ Specify build outputs → references/configuration/tasks.md#outputs\n├─ Handle environment variables → references/environment/README.md\n├─ Set up dev/watch tasks → references/configuration/tasks.md#persistent\n├─ Package-specific config → references/configuration/README.md#package-configurations\n└─ Global settings (cacheDir, daemon) → references/configuration/global-options.md"
      },
      {
        "title": "\"My cache isn't working\"",
        "body": "Cache problems?\n├─ Tasks run but outputs not restored → Missing `outputs` key\n├─ Cache misses unexpectedly → references/caching/gotchas.md\n├─ Need to debug hash inputs → Use --summarize or --dry\n├─ Want to skip cache entirely → Use --force or cache: false\n├─ Remote cache not working → references/caching/remote-cache.md\n└─ Environment causing misses → references/environment/gotchas.md"
      },
      {
        "title": "\"I want to run only changed packages\"",
        "body": "Run only what changed?\n├─ Changed packages + dependents (RECOMMENDED) → turbo run build --affected\n├─ Custom base branch → --affected --affected-base=origin/develop\n├─ Manual git comparison → --filter=...[origin/main]\n└─ See all filter options → references/filtering/README.md\n\n--affected is the primary way to run only changed packages. It automatically compares against the default branch and includes dependents."
      },
      {
        "title": "\"I want to filter packages\"",
        "body": "Filter packages?\n├─ Only changed packages → --affected (see above)\n├─ By package name → --filter=web\n├─ By directory → --filter=./apps/*\n├─ Package + dependencies → --filter=web...\n├─ Package + dependents → --filter=...web\n└─ Complex combinations → references/filtering/patterns.md"
      },
      {
        "title": "\"Environment variables aren't working\"",
        "body": "Environment issues?\n├─ Vars not available at runtime → Strict mode filtering (default)\n├─ Cache hits with wrong env → Var not in `env` key\n├─ .env changes not causing rebuilds → .env not in `inputs`\n├─ CI variables missing → references/environment/gotchas.md\n└─ Framework vars (NEXT_PUBLIC_*) → Auto-included via inference"
      },
      {
        "title": "\"I need to set up CI\"",
        "body": "CI setup?\n├─ GitHub Actions → references/ci/github-actions.md\n├─ Vercel deployment → references/ci/vercel.md\n├─ Remote cache in CI → references/caching/remote-cache.md\n├─ Only build changed packages → --affected flag\n├─ Skip unnecessary builds → turbo-ignore (references/cli/commands.md)\n└─ Skip container setup when no changes → turbo-ignore"
      },
      {
        "title": "\"I want to watch for changes during development\"",
        "body": "Watch mode?\n├─ Re-run tasks on change → turbo watch (references/watch/README.md)\n├─ Dev servers with dependencies → Use `with` key (references/configuration/tasks.md#with)\n├─ Restart dev server on dep change → Use `interruptible: true`\n└─ Persistent dev tasks → Use `persistent: true`"
      },
      {
        "title": "\"I need to create/structure a package\"",
        "body": "Package creation/structure?\n├─ Create an internal package → references/best-practices/packages.md\n├─ Repository structure → references/best-practices/structure.md\n├─ Dependency management → references/best-practices/dependencies.md\n├─ Best practices overview → references/best-practices/README.md\n├─ JIT vs Compiled packages → references/best-practices/packages.md#compilation-strategies\n└─ Sharing code between apps → references/best-practices/README.md#package-types"
      },
      {
        "title": "\"How should I structure my monorepo?\"",
        "body": "Monorepo structure?\n├─ Standard layout (apps/, packages/) → references/best-practices/README.md\n├─ Package types (apps vs libraries) → references/best-practices/README.md#package-types\n├─ Creating internal packages → references/best-practices/packages.md\n├─ TypeScript configuration → references/best-practices/structure.md#typescript-configuration\n├─ ESLint configuration → references/best-practices/structure.md#eslint-configuration\n├─ Dependency management → references/best-practices/dependencies.md\n└─ Enforce package boundaries → references/boundaries/README.md"
      },
      {
        "title": "\"I want to enforce architectural boundaries\"",
        "body": "Enforce boundaries?\n├─ Check for violations → turbo boundaries\n├─ Tag packages → references/boundaries/README.md#tags\n├─ Restrict which packages can import others → references/boundaries/README.md#rule-types\n└─ Prevent cross-package file imports → references/boundaries/README.md"
      },
      {
        "title": "Using turbo Shorthand in Code",
        "body": "turbo run is recommended in package.json scripts and CI pipelines. The shorthand turbo <task> is intended for interactive terminal use.\n\n// WRONG - using shorthand in package.json\n{\n  \"scripts\": {\n    \"build\": \"turbo build\",\n    \"dev\": \"turbo dev\"\n  }\n}\n\n// CORRECT\n{\n  \"scripts\": {\n    \"build\": \"turbo run build\",\n    \"dev\": \"turbo run dev\"\n  }\n}\n\n# WRONG - using shorthand in CI\n- run: turbo build --affected\n\n# CORRECT\n- run: turbo run build --affected"
      },
      {
        "title": "Root Scripts Bypassing Turbo",
        "body": "Root package.json scripts MUST delegate to turbo run, not run tasks directly.\n\n// WRONG - bypasses turbo entirely\n{\n  \"scripts\": {\n    \"build\": \"bun build\",\n    \"dev\": \"bun dev\"\n  }\n}\n\n// CORRECT - delegates to turbo\n{\n  \"scripts\": {\n    \"build\": \"turbo run build\",\n    \"dev\": \"turbo run dev\"\n  }\n}"
      },
      {
        "title": "Using && to Chain Turbo Tasks",
        "body": "Don't chain turbo tasks with &&. Let turbo orchestrate.\n\n// WRONG - turbo task not using turbo run\n{\n  \"scripts\": {\n    \"changeset:publish\": \"bun build && changeset publish\"\n  }\n}\n\n// CORRECT\n{\n  \"scripts\": {\n    \"changeset:publish\": \"turbo run build && changeset publish\"\n  }\n}"
      },
      {
        "title": "prebuild Scripts That Manually Build Dependencies",
        "body": "Scripts like prebuild that manually build other packages bypass Turborepo's dependency graph.\n\n// WRONG - manually building dependencies\n{\n  \"scripts\": {\n    \"prebuild\": \"cd ../../packages/types && bun run build && cd ../utils && bun run build\",\n    \"build\": \"next build\"\n  }\n}\n\nHowever, the fix depends on whether workspace dependencies are declared:\n\nIf dependencies ARE declared (e.g., \"@repo/types\": \"workspace:*\" in package.json), remove the prebuild script. Turbo's dependsOn: [\"^build\"] handles this automatically.\n\n\nIf dependencies are NOT declared, the prebuild exists because ^build won't trigger without a dependency relationship. The fix is to:\n\nAdd the dependency to package.json: \"@repo/types\": \"workspace:*\"\nThen remove the prebuild script\n\n// CORRECT - declare dependency, let turbo handle build order\n// package.json\n{\n  \"dependencies\": {\n    \"@repo/types\": \"workspace:*\",\n    \"@repo/utils\": \"workspace:*\"\n  },\n  \"scripts\": {\n    \"build\": \"next build\"\n  }\n}\n\n// turbo.json\n{\n  \"tasks\": {\n    \"build\": {\n      \"dependsOn\": [\"^build\"]\n    }\n  }\n}\n\nKey insight: ^build only runs build in packages listed as dependencies. No dependency declaration = no automatic build ordering."
      },
      {
        "title": "Overly Broad globalDependencies",
        "body": "globalDependencies affects ALL tasks in ALL packages. Be specific.\n\n// WRONG - heavy hammer, affects all hashes\n{\n  \"globalDependencies\": [\"**/.env.*local\"]\n}\n\n// BETTER - move to task-level inputs\n{\n  \"globalDependencies\": [\".env\"],\n  \"tasks\": {\n    \"build\": {\n      \"inputs\": [\"$TURBO_DEFAULT$\", \".env*\"],\n      \"outputs\": [\"dist/**\"]\n    }\n  }\n}"
      },
      {
        "title": "Repetitive Task Configuration",
        "body": "Look for repeated configuration across tasks that can be collapsed. Turborepo supports shared configuration patterns.\n\n// WRONG - repetitive env and inputs across tasks\n{\n  \"tasks\": {\n    \"build\": {\n      \"env\": [\"API_URL\", \"DATABASE_URL\"],\n      \"inputs\": [\"$TURBO_DEFAULT$\", \".env*\"]\n    },\n    \"test\": {\n      \"env\": [\"API_URL\", \"DATABASE_URL\"],\n      \"inputs\": [\"$TURBO_DEFAULT$\", \".env*\"]\n    },\n    \"dev\": {\n      \"env\": [\"API_URL\", \"DATABASE_URL\"],\n      \"inputs\": [\"$TURBO_DEFAULT$\", \".env*\"],\n      \"cache\": false,\n      \"persistent\": true\n    }\n  }\n}\n\n// BETTER - use globalEnv and globalDependencies for shared config\n{\n  \"globalEnv\": [\"API_URL\", \"DATABASE_URL\"],\n  \"globalDependencies\": [\".env*\"],\n  \"tasks\": {\n    \"build\": {},\n    \"test\": {},\n    \"dev\": {\n      \"cache\": false,\n      \"persistent\": true\n    }\n  }\n}\n\nWhen to use global vs task-level:\n\nglobalEnv / globalDependencies - affects ALL tasks, use for truly shared config\nTask-level env / inputs - use when only specific tasks need it"
      },
      {
        "title": "NOT an Anti-Pattern: Large env Arrays",
        "body": "A large env array (even 50+ variables) is not a problem. It usually means the user was thorough about declaring their build's environment dependencies. Do not flag this as an issue."
      },
      {
        "title": "Using --parallel Flag",
        "body": "The --parallel flag bypasses Turborepo's dependency graph. If tasks need parallel execution, configure dependsOn correctly instead.\n\n# WRONG - bypasses dependency graph\nturbo run lint --parallel\n\n# CORRECT - configure tasks to allow parallel execution\n# In turbo.json, set dependsOn appropriately (or use transit nodes)\nturbo run lint"
      },
      {
        "title": "Package-Specific Task Overrides in Root turbo.json",
        "body": "When multiple packages need different task configurations, use Package Configurations (turbo.json in each package) instead of cluttering root turbo.json with package#task overrides.\n\n// WRONG - root turbo.json with many package-specific overrides\n{\n  \"tasks\": {\n    \"test\": { \"dependsOn\": [\"build\"] },\n    \"@repo/web#test\": { \"outputs\": [\"coverage/**\"] },\n    \"@repo/api#test\": { \"outputs\": [\"coverage/**\"] },\n    \"@repo/utils#test\": { \"outputs\": [] },\n    \"@repo/cli#test\": { \"outputs\": [] },\n    \"@repo/core#test\": { \"outputs\": [] }\n  }\n}\n\n// CORRECT - use Package Configurations\n// Root turbo.json - base config only\n{\n  \"tasks\": {\n    \"test\": { \"dependsOn\": [\"build\"] }\n  }\n}\n\n// packages/web/turbo.json - package-specific override\n{\n  \"extends\": [\"//\"],\n  \"tasks\": {\n    \"test\": { \"outputs\": [\"coverage/**\"] }\n  }\n}\n\n// packages/api/turbo.json\n{\n  \"extends\": [\"//\"],\n  \"tasks\": {\n    \"test\": { \"outputs\": [\"coverage/**\"] }\n  }\n}\n\nBenefits of Package Configurations:\n\nKeeps configuration close to the code it affects\nRoot turbo.json stays clean and focused on base patterns\nEasier to understand what's special about each package\nWorks with $TURBO_EXTENDS$ to inherit + extend arrays\n\nWhen to use package#task in root:\n\nSingle package needs a unique dependency (e.g., \"deploy\": { \"dependsOn\": [\"web#build\"] })\nTemporary override while migrating\n\nSee references/configuration/README.md#package-configurations for full details."
      },
      {
        "title": "Using ../ to Traverse Out of Package in inputs",
        "body": "Don't use relative paths like ../ to reference files outside the package. Use $TURBO_ROOT$ instead.\n\n// WRONG - traversing out of package\n{\n  \"tasks\": {\n    \"build\": {\n      \"inputs\": [\"$TURBO_DEFAULT$\", \"../shared-config.json\"]\n    }\n  }\n}\n\n// CORRECT - use $TURBO_ROOT$ for repo root\n{\n  \"tasks\": {\n    \"build\": {\n      \"inputs\": [\"$TURBO_DEFAULT$\", \"$TURBO_ROOT$/shared-config.json\"]\n    }\n  }\n}"
      },
      {
        "title": "Missing outputs for File-Producing Tasks",
        "body": "Before flagging missing outputs, check what the task actually produces:\n\nRead the package's script (e.g., \"build\": \"tsc\", \"test\": \"vitest\")\nDetermine if it writes files to disk or only outputs to stdout\nOnly flag if the task produces files that should be cached\n\n// WRONG: build produces files but they're not cached\n{\n  \"tasks\": {\n    \"build\": {\n      \"dependsOn\": [\"^build\"]\n    }\n  }\n}\n\n// CORRECT: build outputs are cached\n{\n  \"tasks\": {\n    \"build\": {\n      \"dependsOn\": [\"^build\"],\n      \"outputs\": [\"dist/**\"]\n    }\n  }\n}\n\nCommon outputs by framework:\n\nNext.js: [\".next/**\", \"!.next/cache/**\"]\nVite/Rollup: [\"dist/**\"]\ntsc: [\"dist/**\"] or custom outDir\n\nTypeScript --noEmit can still produce cache files:\n\nWhen incremental: true in tsconfig.json, tsc --noEmit writes .tsbuildinfo files even without emitting JS. Check the tsconfig before assuming no outputs:\n\n// If tsconfig has incremental: true, tsc --noEmit produces cache files\n{\n  \"tasks\": {\n    \"typecheck\": {\n      \"outputs\": [\"node_modules/.cache/tsbuildinfo.json\"] // or wherever tsBuildInfoFile points\n    }\n  }\n}\n\nTo determine correct outputs for TypeScript tasks:\n\nCheck if incremental or composite is enabled in tsconfig\nCheck tsBuildInfoFile for custom cache location (default: alongside outDir or in project root)\nIf no incremental mode, tsc --noEmit produces no files"
      },
      {
        "title": "^build vs build Confusion",
        "body": "{\n  \"tasks\": {\n    // ^build = run build in DEPENDENCIES first (other packages this one imports)\n    \"build\": {\n      \"dependsOn\": [\"^build\"]\n    },\n    // build (no ^) = run build in SAME PACKAGE first\n    \"test\": {\n      \"dependsOn\": [\"build\"]\n    },\n    // pkg#task = specific package's task\n    \"deploy\": {\n      \"dependsOn\": [\"web#build\"]\n    }\n  }\n}"
      },
      {
        "title": "Environment Variables Not Hashed",
        "body": "// WRONG: API_URL changes won't cause rebuilds\n{\n  \"tasks\": {\n    \"build\": {\n      \"outputs\": [\"dist/**\"]\n    }\n  }\n}\n\n// CORRECT: API_URL changes invalidate cache\n{\n  \"tasks\": {\n    \"build\": {\n      \"outputs\": [\"dist/**\"],\n      \"env\": [\"API_URL\", \"API_KEY\"]\n    }\n  }\n}"
      },
      {
        "title": ".env Files Not in Inputs",
        "body": "Turbo does NOT load .env files - your framework does. But Turbo needs to know about changes:\n\n// WRONG: .env changes don't invalidate cache\n{\n  \"tasks\": {\n    \"build\": {\n      \"env\": [\"API_URL\"]\n    }\n  }\n}\n\n// CORRECT: .env file changes invalidate cache\n{\n  \"tasks\": {\n    \"build\": {\n      \"env\": [\"API_URL\"],\n      \"inputs\": [\"$TURBO_DEFAULT$\", \".env\", \".env.*\"]\n    }\n  }\n}"
      },
      {
        "title": "Root .env File in Monorepo",
        "body": "A .env file at the repo root is an anti-pattern — even for small monorepos or starter templates. It creates implicit coupling between packages and makes it unclear which packages depend on which variables.\n\n// WRONG - root .env affects all packages implicitly\nmy-monorepo/\n├── .env              # Which packages use this?\n├── apps/\n│   ├── web/\n│   └── api/\n└── packages/\n\n// CORRECT - .env files in packages that need them\nmy-monorepo/\n├── apps/\n│   ├── web/\n│   │   └── .env      # Clear: web needs DATABASE_URL\n│   └── api/\n│       └── .env      # Clear: api needs API_KEY\n└── packages/\n\nProblems with root .env:\n\nUnclear which packages consume which variables\nAll packages get all variables (even ones they don't need)\nCache invalidation is coarse-grained (root .env change invalidates everything)\nSecurity risk: packages may accidentally access sensitive vars meant for others\nBad habits start small — starter templates should model correct patterns\n\nIf you must share variables, use globalEnv to be explicit about what's shared, and document why."
      },
      {
        "title": "Strict Mode Filtering CI Variables",
        "body": "By default, Turborepo filters environment variables to only those in env/globalEnv. CI variables may be missing:\n\n// If CI scripts need GITHUB_TOKEN but it's not in env:\n{\n  \"globalPassThroughEnv\": [\"GITHUB_TOKEN\", \"CI\"],\n  \"tasks\": { ... }\n}\n\nOr use --env-mode=loose (not recommended for production)."
      },
      {
        "title": "Shared Code in Apps (Should Be a Package)",
        "body": "// WRONG: Shared code inside an app\napps/\n  web/\n    shared/          # This breaks monorepo principles!\n      utils.ts\n\n// CORRECT: Extract to a package\npackages/\n  utils/\n    src/utils.ts"
      },
      {
        "title": "Accessing Files Across Package Boundaries",
        "body": "// WRONG: Reaching into another package's internals\nimport { Button } from \"../../packages/ui/src/button\";\n\n// CORRECT: Install and import properly\nimport { Button } from \"@repo/ui/button\";"
      },
      {
        "title": "Too Many Root Dependencies",
        "body": "// WRONG: App dependencies in root\n{\n  \"dependencies\": {\n    \"react\": \"^18\",\n    \"next\": \"^14\"\n  }\n}\n\n// CORRECT: Only repo tools in root\n{\n  \"devDependencies\": {\n    \"turbo\": \"latest\"\n  }\n}"
      },
      {
        "title": "Standard Build Pipeline",
        "body": "{\n  \"$schema\": \"https://turborepo.dev/schema.v2.json\",\n  \"tasks\": {\n    \"build\": {\n      \"dependsOn\": [\"^build\"],\n      \"outputs\": [\"dist/**\", \".next/**\", \"!.next/cache/**\"]\n    },\n    \"dev\": {\n      \"cache\": false,\n      \"persistent\": true\n    }\n  }\n}\n\nAdd a transit task if you have tasks that need parallel execution with cache invalidation (see below)."
      },
      {
        "title": "Dev Task with ^dev Pattern (for turbo watch)",
        "body": "A dev task with dependsOn: [\"^dev\"] and persistent: false in root turbo.json may look unusual but is correct for turbo watch workflows:\n\n// Root turbo.json\n{\n  \"tasks\": {\n    \"dev\": {\n      \"dependsOn\": [\"^dev\"],\n      \"cache\": false,\n      \"persistent\": false  // Packages have one-shot dev scripts\n    }\n  }\n}\n\n// Package turbo.json (apps/web/turbo.json)\n{\n  \"extends\": [\"//\"],\n  \"tasks\": {\n    \"dev\": {\n      \"persistent\": true  // Apps run long-running dev servers\n    }\n  }\n}\n\nWhy this works:\n\nPackages (e.g., @acme/db, @acme/validators) have \"dev\": \"tsc\" — one-shot type generation that completes quickly\nApps override with persistent: true for actual dev servers (Next.js, etc.)\nturbo watch re-runs the one-shot package dev scripts when source files change, keeping types in sync\n\nIntended usage: Run turbo watch dev (not turbo run dev). Watch mode re-executes one-shot tasks on file changes while keeping persistent tasks running.\n\nAlternative pattern: Use a separate task name like prepare or generate for one-shot dependency builds to make the intent clearer:\n\n{\n  \"tasks\": {\n    \"prepare\": {\n      \"dependsOn\": [\"^prepare\"],\n      \"outputs\": [\"dist/**\"]\n    },\n    \"dev\": {\n      \"dependsOn\": [\"prepare\"],\n      \"cache\": false,\n      \"persistent\": true\n    }\n  }\n}"
      },
      {
        "title": "Transit Nodes for Parallel Tasks with Cache Invalidation",
        "body": "Some tasks can run in parallel (don't need built output from dependencies) but must invalidate cache when dependency source code changes.\n\nThe problem with dependsOn: [\"^taskname\"]:\n\nForces sequential execution (slow)\n\nThe problem with dependsOn: [] (no dependencies):\n\nAllows parallel execution (fast)\nBut cache is INCORRECT - changing dependency source won't invalidate cache\n\nTransit Nodes solve both:\n\n{\n  \"tasks\": {\n    \"transit\": { \"dependsOn\": [\"^transit\"] },\n    \"my-task\": { \"dependsOn\": [\"transit\"] }\n  }\n}\n\nThe transit task creates dependency relationships without matching any actual script, so tasks run in parallel with correct cache invalidation.\n\nHow to identify tasks that need this pattern: Look for tasks that read source files from dependencies but don't need their build outputs."
      },
      {
        "title": "With Environment Variables",
        "body": "{\n  \"globalEnv\": [\"NODE_ENV\"],\n  \"globalDependencies\": [\".env\"],\n  \"tasks\": {\n    \"build\": {\n      \"dependsOn\": [\"^build\"],\n      \"outputs\": [\"dist/**\"],\n      \"env\": [\"API_URL\", \"DATABASE_URL\"]\n    }\n  }\n}"
      },
      {
        "title": "Configuration",
        "body": "FilePurposeconfiguration/README.mdturbo.json overview, Package Configurationsconfiguration/tasks.mddependsOn, outputs, inputs, env, cache, persistentconfiguration/global-options.mdglobalEnv, globalDependencies, cacheDir, daemon, envModeconfiguration/gotchas.mdCommon configuration mistakes"
      },
      {
        "title": "Caching",
        "body": "FilePurposecaching/README.mdHow caching works, hash inputscaching/remote-cache.mdVercel Remote Cache, self-hosted, login/linkcaching/gotchas.mdDebugging cache misses, --summarize, --dry"
      },
      {
        "title": "Environment Variables",
        "body": "FilePurposeenvironment/README.mdenv, globalEnv, passThroughEnvenvironment/modes.mdStrict vs Loose mode, framework inferenceenvironment/gotchas.md.env files, CI issues"
      },
      {
        "title": "Filtering",
        "body": "FilePurposefiltering/README.md--filter syntax overviewfiltering/patterns.mdCommon filter patterns"
      },
      {
        "title": "CI/CD",
        "body": "FilePurposeci/README.mdGeneral CI principlesci/github-actions.mdComplete GitHub Actions setupci/vercel.mdVercel deployment, turbo-ignoreci/patterns.md--affected, caching strategies"
      },
      {
        "title": "CLI",
        "body": "FilePurposecli/README.mdturbo run basicscli/commands.mdturbo run flags, turbo-ignore, other commands"
      },
      {
        "title": "Best Practices",
        "body": "FilePurposebest-practices/README.mdMonorepo best practices overviewbest-practices/structure.mdRepository structure, workspace config, TypeScript/ESLint setupbest-practices/packages.mdCreating internal packages, JIT vs Compiled, exportsbest-practices/dependencies.mdDependency management, installing, version sync"
      },
      {
        "title": "Watch Mode",
        "body": "FilePurposewatch/README.mdturbo watch, interruptible tasks, dev workflows"
      },
      {
        "title": "Boundaries (Experimental)",
        "body": "FilePurposeboundaries/README.mdEnforce package isolation, tag-based dependency rules"
      },
      {
        "title": "Source Documentation",
        "body": "This skill is based on the official Turborepo documentation at:\n\nSource: docs/site/content/docs/ in the Turborepo repository\nLive: https://turborepo.dev/docs"
      }
    ],
    "body": "Turborepo\n\nBuild system for JavaScript/TypeScript monorepos. Caches task outputs and runs tasks in parallel based on dependency graph.\n\nInstallation\nOpenClaw / Moltbot / Clawbot\nnpx clawhub@latest install turborepo\n\nNEVER\nNEVER create root tasks - Always create package-level tasks in each package's package.json\nNEVER use turbo <task> shorthand in code - Use turbo run <task> in package.json and CI\nNEVER bypass turbo - Root scripts must delegate via turbo run, not run tasks directly\nNEVER chain turbo tasks with && - Let turbo orchestrate dependencies via dependsOn\nNEVER use --parallel flag - Configure dependsOn correctly instead\nNEVER put .env at repo root - Use package-level .env files for clarity\nNEVER use ../ in inputs - Use $TURBO_ROOT$/path for repo root files\nIMPORTANT: Package Tasks, Not Root Tasks\n\nDO NOT create Root Tasks. ALWAYS create package tasks.\n\nWhen creating tasks/scripts/pipelines, you MUST:\n\nAdd the script to each relevant package's package.json\nRegister the task in root turbo.json\nRoot package.json only delegates via turbo run <task>\n\nDO NOT put task logic in root package.json. This defeats Turborepo's parallelization.\n\n// DO THIS: Scripts in each package\n// apps/web/package.json\n{ \"scripts\": { \"build\": \"next build\", \"lint\": \"eslint .\", \"test\": \"vitest\" } }\n\n// apps/api/package.json\n{ \"scripts\": { \"build\": \"tsc\", \"lint\": \"eslint .\", \"test\": \"vitest\" } }\n\n// packages/ui/package.json\n{ \"scripts\": { \"build\": \"tsc\", \"lint\": \"eslint .\", \"test\": \"vitest\" } }\n\n// turbo.json - register tasks\n{\n  \"tasks\": {\n    \"build\": { \"dependsOn\": [\"^build\"], \"outputs\": [\"dist/**\"] },\n    \"lint\": {},\n    \"test\": { \"dependsOn\": [\"build\"] }\n  }\n}\n\n// Root package.json - ONLY delegates, no task logic\n{\n  \"scripts\": {\n    \"build\": \"turbo run build\",\n    \"lint\": \"turbo run lint\",\n    \"test\": \"turbo run test\"\n  }\n}\n\n// DO NOT DO THIS - defeats parallelization\n// Root package.json\n{\n  \"scripts\": {\n    \"build\": \"cd apps/web && next build && cd ../api && tsc\",\n    \"lint\": \"eslint apps/ packages/\",\n    \"test\": \"vitest\"\n  }\n}\n\n\nRoot Tasks (//#taskname) are ONLY for tasks that truly cannot exist in packages (rare).\n\nSecondary Rule: turbo run vs turbo\n\nAlways use turbo run when the command is written into code:\n\n// package.json - ALWAYS \"turbo run\"\n{\n  \"scripts\": {\n    \"build\": \"turbo run build\"\n  }\n}\n\n# CI workflows - ALWAYS \"turbo run\"\n- run: turbo run build --affected\n\n\nThe shorthand turbo <tasks> is ONLY for one-off terminal commands typed directly by humans or agents. Never write turbo build into package.json, CI, or scripts.\n\nQuick Decision Trees\n\"I need to configure a task\"\nConfigure a task?\n├─ Define task dependencies → references/configuration/tasks.md\n├─ Lint/check-types (parallel + caching) → Use Transit Nodes pattern (see below)\n├─ Specify build outputs → references/configuration/tasks.md#outputs\n├─ Handle environment variables → references/environment/README.md\n├─ Set up dev/watch tasks → references/configuration/tasks.md#persistent\n├─ Package-specific config → references/configuration/README.md#package-configurations\n└─ Global settings (cacheDir, daemon) → references/configuration/global-options.md\n\n\"My cache isn't working\"\nCache problems?\n├─ Tasks run but outputs not restored → Missing `outputs` key\n├─ Cache misses unexpectedly → references/caching/gotchas.md\n├─ Need to debug hash inputs → Use --summarize or --dry\n├─ Want to skip cache entirely → Use --force or cache: false\n├─ Remote cache not working → references/caching/remote-cache.md\n└─ Environment causing misses → references/environment/gotchas.md\n\n\"I want to run only changed packages\"\nRun only what changed?\n├─ Changed packages + dependents (RECOMMENDED) → turbo run build --affected\n├─ Custom base branch → --affected --affected-base=origin/develop\n├─ Manual git comparison → --filter=...[origin/main]\n└─ See all filter options → references/filtering/README.md\n\n\n--affected is the primary way to run only changed packages. It automatically compares against the default branch and includes dependents.\n\n\"I want to filter packages\"\nFilter packages?\n├─ Only changed packages → --affected (see above)\n├─ By package name → --filter=web\n├─ By directory → --filter=./apps/*\n├─ Package + dependencies → --filter=web...\n├─ Package + dependents → --filter=...web\n└─ Complex combinations → references/filtering/patterns.md\n\n\"Environment variables aren't working\"\nEnvironment issues?\n├─ Vars not available at runtime → Strict mode filtering (default)\n├─ Cache hits with wrong env → Var not in `env` key\n├─ .env changes not causing rebuilds → .env not in `inputs`\n├─ CI variables missing → references/environment/gotchas.md\n└─ Framework vars (NEXT_PUBLIC_*) → Auto-included via inference\n\n\"I need to set up CI\"\nCI setup?\n├─ GitHub Actions → references/ci/github-actions.md\n├─ Vercel deployment → references/ci/vercel.md\n├─ Remote cache in CI → references/caching/remote-cache.md\n├─ Only build changed packages → --affected flag\n├─ Skip unnecessary builds → turbo-ignore (references/cli/commands.md)\n└─ Skip container setup when no changes → turbo-ignore\n\n\"I want to watch for changes during development\"\nWatch mode?\n├─ Re-run tasks on change → turbo watch (references/watch/README.md)\n├─ Dev servers with dependencies → Use `with` key (references/configuration/tasks.md#with)\n├─ Restart dev server on dep change → Use `interruptible: true`\n└─ Persistent dev tasks → Use `persistent: true`\n\n\"I need to create/structure a package\"\nPackage creation/structure?\n├─ Create an internal package → references/best-practices/packages.md\n├─ Repository structure → references/best-practices/structure.md\n├─ Dependency management → references/best-practices/dependencies.md\n├─ Best practices overview → references/best-practices/README.md\n├─ JIT vs Compiled packages → references/best-practices/packages.md#compilation-strategies\n└─ Sharing code between apps → references/best-practices/README.md#package-types\n\n\"How should I structure my monorepo?\"\nMonorepo structure?\n├─ Standard layout (apps/, packages/) → references/best-practices/README.md\n├─ Package types (apps vs libraries) → references/best-practices/README.md#package-types\n├─ Creating internal packages → references/best-practices/packages.md\n├─ TypeScript configuration → references/best-practices/structure.md#typescript-configuration\n├─ ESLint configuration → references/best-practices/structure.md#eslint-configuration\n├─ Dependency management → references/best-practices/dependencies.md\n└─ Enforce package boundaries → references/boundaries/README.md\n\n\"I want to enforce architectural boundaries\"\nEnforce boundaries?\n├─ Check for violations → turbo boundaries\n├─ Tag packages → references/boundaries/README.md#tags\n├─ Restrict which packages can import others → references/boundaries/README.md#rule-types\n└─ Prevent cross-package file imports → references/boundaries/README.md\n\nCritical Anti-Patterns\nUsing turbo Shorthand in Code\n\nturbo run is recommended in package.json scripts and CI pipelines. The shorthand turbo <task> is intended for interactive terminal use.\n\n// WRONG - using shorthand in package.json\n{\n  \"scripts\": {\n    \"build\": \"turbo build\",\n    \"dev\": \"turbo dev\"\n  }\n}\n\n// CORRECT\n{\n  \"scripts\": {\n    \"build\": \"turbo run build\",\n    \"dev\": \"turbo run dev\"\n  }\n}\n\n# WRONG - using shorthand in CI\n- run: turbo build --affected\n\n# CORRECT\n- run: turbo run build --affected\n\nRoot Scripts Bypassing Turbo\n\nRoot package.json scripts MUST delegate to turbo run, not run tasks directly.\n\n// WRONG - bypasses turbo entirely\n{\n  \"scripts\": {\n    \"build\": \"bun build\",\n    \"dev\": \"bun dev\"\n  }\n}\n\n// CORRECT - delegates to turbo\n{\n  \"scripts\": {\n    \"build\": \"turbo run build\",\n    \"dev\": \"turbo run dev\"\n  }\n}\n\nUsing && to Chain Turbo Tasks\n\nDon't chain turbo tasks with &&. Let turbo orchestrate.\n\n// WRONG - turbo task not using turbo run\n{\n  \"scripts\": {\n    \"changeset:publish\": \"bun build && changeset publish\"\n  }\n}\n\n// CORRECT\n{\n  \"scripts\": {\n    \"changeset:publish\": \"turbo run build && changeset publish\"\n  }\n}\n\nprebuild Scripts That Manually Build Dependencies\n\nScripts like prebuild that manually build other packages bypass Turborepo's dependency graph.\n\n// WRONG - manually building dependencies\n{\n  \"scripts\": {\n    \"prebuild\": \"cd ../../packages/types && bun run build && cd ../utils && bun run build\",\n    \"build\": \"next build\"\n  }\n}\n\n\nHowever, the fix depends on whether workspace dependencies are declared:\n\nIf dependencies ARE declared (e.g., \"@repo/types\": \"workspace:*\" in package.json), remove the prebuild script. Turbo's dependsOn: [\"^build\"] handles this automatically.\n\nIf dependencies are NOT declared, the prebuild exists because ^build won't trigger without a dependency relationship. The fix is to:\n\nAdd the dependency to package.json: \"@repo/types\": \"workspace:*\"\nThen remove the prebuild script\n// CORRECT - declare dependency, let turbo handle build order\n// package.json\n{\n  \"dependencies\": {\n    \"@repo/types\": \"workspace:*\",\n    \"@repo/utils\": \"workspace:*\"\n  },\n  \"scripts\": {\n    \"build\": \"next build\"\n  }\n}\n\n// turbo.json\n{\n  \"tasks\": {\n    \"build\": {\n      \"dependsOn\": [\"^build\"]\n    }\n  }\n}\n\n\nKey insight: ^build only runs build in packages listed as dependencies. No dependency declaration = no automatic build ordering.\n\nOverly Broad globalDependencies\n\nglobalDependencies affects ALL tasks in ALL packages. Be specific.\n\n// WRONG - heavy hammer, affects all hashes\n{\n  \"globalDependencies\": [\"**/.env.*local\"]\n}\n\n// BETTER - move to task-level inputs\n{\n  \"globalDependencies\": [\".env\"],\n  \"tasks\": {\n    \"build\": {\n      \"inputs\": [\"$TURBO_DEFAULT$\", \".env*\"],\n      \"outputs\": [\"dist/**\"]\n    }\n  }\n}\n\nRepetitive Task Configuration\n\nLook for repeated configuration across tasks that can be collapsed. Turborepo supports shared configuration patterns.\n\n// WRONG - repetitive env and inputs across tasks\n{\n  \"tasks\": {\n    \"build\": {\n      \"env\": [\"API_URL\", \"DATABASE_URL\"],\n      \"inputs\": [\"$TURBO_DEFAULT$\", \".env*\"]\n    },\n    \"test\": {\n      \"env\": [\"API_URL\", \"DATABASE_URL\"],\n      \"inputs\": [\"$TURBO_DEFAULT$\", \".env*\"]\n    },\n    \"dev\": {\n      \"env\": [\"API_URL\", \"DATABASE_URL\"],\n      \"inputs\": [\"$TURBO_DEFAULT$\", \".env*\"],\n      \"cache\": false,\n      \"persistent\": true\n    }\n  }\n}\n\n// BETTER - use globalEnv and globalDependencies for shared config\n{\n  \"globalEnv\": [\"API_URL\", \"DATABASE_URL\"],\n  \"globalDependencies\": [\".env*\"],\n  \"tasks\": {\n    \"build\": {},\n    \"test\": {},\n    \"dev\": {\n      \"cache\": false,\n      \"persistent\": true\n    }\n  }\n}\n\n\nWhen to use global vs task-level:\n\nglobalEnv / globalDependencies - affects ALL tasks, use for truly shared config\nTask-level env / inputs - use when only specific tasks need it\nNOT an Anti-Pattern: Large env Arrays\n\nA large env array (even 50+ variables) is not a problem. It usually means the user was thorough about declaring their build's environment dependencies. Do not flag this as an issue.\n\nUsing --parallel Flag\n\nThe --parallel flag bypasses Turborepo's dependency graph. If tasks need parallel execution, configure dependsOn correctly instead.\n\n# WRONG - bypasses dependency graph\nturbo run lint --parallel\n\n# CORRECT - configure tasks to allow parallel execution\n# In turbo.json, set dependsOn appropriately (or use transit nodes)\nturbo run lint\n\nPackage-Specific Task Overrides in Root turbo.json\n\nWhen multiple packages need different task configurations, use Package Configurations (turbo.json in each package) instead of cluttering root turbo.json with package#task overrides.\n\n// WRONG - root turbo.json with many package-specific overrides\n{\n  \"tasks\": {\n    \"test\": { \"dependsOn\": [\"build\"] },\n    \"@repo/web#test\": { \"outputs\": [\"coverage/**\"] },\n    \"@repo/api#test\": { \"outputs\": [\"coverage/**\"] },\n    \"@repo/utils#test\": { \"outputs\": [] },\n    \"@repo/cli#test\": { \"outputs\": [] },\n    \"@repo/core#test\": { \"outputs\": [] }\n  }\n}\n\n// CORRECT - use Package Configurations\n// Root turbo.json - base config only\n{\n  \"tasks\": {\n    \"test\": { \"dependsOn\": [\"build\"] }\n  }\n}\n\n// packages/web/turbo.json - package-specific override\n{\n  \"extends\": [\"//\"],\n  \"tasks\": {\n    \"test\": { \"outputs\": [\"coverage/**\"] }\n  }\n}\n\n// packages/api/turbo.json\n{\n  \"extends\": [\"//\"],\n  \"tasks\": {\n    \"test\": { \"outputs\": [\"coverage/**\"] }\n  }\n}\n\n\nBenefits of Package Configurations:\n\nKeeps configuration close to the code it affects\nRoot turbo.json stays clean and focused on base patterns\nEasier to understand what's special about each package\nWorks with $TURBO_EXTENDS$ to inherit + extend arrays\n\nWhen to use package#task in root:\n\nSingle package needs a unique dependency (e.g., \"deploy\": { \"dependsOn\": [\"web#build\"] })\nTemporary override while migrating\n\nSee references/configuration/README.md#package-configurations for full details.\n\nUsing ../ to Traverse Out of Package in inputs\n\nDon't use relative paths like ../ to reference files outside the package. Use $TURBO_ROOT$ instead.\n\n// WRONG - traversing out of package\n{\n  \"tasks\": {\n    \"build\": {\n      \"inputs\": [\"$TURBO_DEFAULT$\", \"../shared-config.json\"]\n    }\n  }\n}\n\n// CORRECT - use $TURBO_ROOT$ for repo root\n{\n  \"tasks\": {\n    \"build\": {\n      \"inputs\": [\"$TURBO_DEFAULT$\", \"$TURBO_ROOT$/shared-config.json\"]\n    }\n  }\n}\n\nMissing outputs for File-Producing Tasks\n\nBefore flagging missing outputs, check what the task actually produces:\n\nRead the package's script (e.g., \"build\": \"tsc\", \"test\": \"vitest\")\nDetermine if it writes files to disk or only outputs to stdout\nOnly flag if the task produces files that should be cached\n// WRONG: build produces files but they're not cached\n{\n  \"tasks\": {\n    \"build\": {\n      \"dependsOn\": [\"^build\"]\n    }\n  }\n}\n\n// CORRECT: build outputs are cached\n{\n  \"tasks\": {\n    \"build\": {\n      \"dependsOn\": [\"^build\"],\n      \"outputs\": [\"dist/**\"]\n    }\n  }\n}\n\n\nCommon outputs by framework:\n\nNext.js: [\".next/**\", \"!.next/cache/**\"]\nVite/Rollup: [\"dist/**\"]\ntsc: [\"dist/**\"] or custom outDir\n\nTypeScript --noEmit can still produce cache files:\n\nWhen incremental: true in tsconfig.json, tsc --noEmit writes .tsbuildinfo files even without emitting JS. Check the tsconfig before assuming no outputs:\n\n// If tsconfig has incremental: true, tsc --noEmit produces cache files\n{\n  \"tasks\": {\n    \"typecheck\": {\n      \"outputs\": [\"node_modules/.cache/tsbuildinfo.json\"] // or wherever tsBuildInfoFile points\n    }\n  }\n}\n\n\nTo determine correct outputs for TypeScript tasks:\n\nCheck if incremental or composite is enabled in tsconfig\nCheck tsBuildInfoFile for custom cache location (default: alongside outDir or in project root)\nIf no incremental mode, tsc --noEmit produces no files\n^build vs build Confusion\n{\n  \"tasks\": {\n    // ^build = run build in DEPENDENCIES first (other packages this one imports)\n    \"build\": {\n      \"dependsOn\": [\"^build\"]\n    },\n    // build (no ^) = run build in SAME PACKAGE first\n    \"test\": {\n      \"dependsOn\": [\"build\"]\n    },\n    // pkg#task = specific package's task\n    \"deploy\": {\n      \"dependsOn\": [\"web#build\"]\n    }\n  }\n}\n\nEnvironment Variables Not Hashed\n// WRONG: API_URL changes won't cause rebuilds\n{\n  \"tasks\": {\n    \"build\": {\n      \"outputs\": [\"dist/**\"]\n    }\n  }\n}\n\n// CORRECT: API_URL changes invalidate cache\n{\n  \"tasks\": {\n    \"build\": {\n      \"outputs\": [\"dist/**\"],\n      \"env\": [\"API_URL\", \"API_KEY\"]\n    }\n  }\n}\n\n.env Files Not in Inputs\n\nTurbo does NOT load .env files - your framework does. But Turbo needs to know about changes:\n\n// WRONG: .env changes don't invalidate cache\n{\n  \"tasks\": {\n    \"build\": {\n      \"env\": [\"API_URL\"]\n    }\n  }\n}\n\n// CORRECT: .env file changes invalidate cache\n{\n  \"tasks\": {\n    \"build\": {\n      \"env\": [\"API_URL\"],\n      \"inputs\": [\"$TURBO_DEFAULT$\", \".env\", \".env.*\"]\n    }\n  }\n}\n\nRoot .env File in Monorepo\n\nA .env file at the repo root is an anti-pattern — even for small monorepos or starter templates. It creates implicit coupling between packages and makes it unclear which packages depend on which variables.\n\n// WRONG - root .env affects all packages implicitly\nmy-monorepo/\n├── .env              # Which packages use this?\n├── apps/\n│   ├── web/\n│   └── api/\n└── packages/\n\n// CORRECT - .env files in packages that need them\nmy-monorepo/\n├── apps/\n│   ├── web/\n│   │   └── .env      # Clear: web needs DATABASE_URL\n│   └── api/\n│       └── .env      # Clear: api needs API_KEY\n└── packages/\n\n\nProblems with root .env:\n\nUnclear which packages consume which variables\nAll packages get all variables (even ones they don't need)\nCache invalidation is coarse-grained (root .env change invalidates everything)\nSecurity risk: packages may accidentally access sensitive vars meant for others\nBad habits start small — starter templates should model correct patterns\n\nIf you must share variables, use globalEnv to be explicit about what's shared, and document why.\n\nStrict Mode Filtering CI Variables\n\nBy default, Turborepo filters environment variables to only those in env/globalEnv. CI variables may be missing:\n\n// If CI scripts need GITHUB_TOKEN but it's not in env:\n{\n  \"globalPassThroughEnv\": [\"GITHUB_TOKEN\", \"CI\"],\n  \"tasks\": { ... }\n}\n\n\nOr use --env-mode=loose (not recommended for production).\n\nShared Code in Apps (Should Be a Package)\n// WRONG: Shared code inside an app\napps/\n  web/\n    shared/          # This breaks monorepo principles!\n      utils.ts\n\n// CORRECT: Extract to a package\npackages/\n  utils/\n    src/utils.ts\n\nAccessing Files Across Package Boundaries\n// WRONG: Reaching into another package's internals\nimport { Button } from \"../../packages/ui/src/button\";\n\n// CORRECT: Install and import properly\nimport { Button } from \"@repo/ui/button\";\n\nToo Many Root Dependencies\n// WRONG: App dependencies in root\n{\n  \"dependencies\": {\n    \"react\": \"^18\",\n    \"next\": \"^14\"\n  }\n}\n\n// CORRECT: Only repo tools in root\n{\n  \"devDependencies\": {\n    \"turbo\": \"latest\"\n  }\n}\n\nCommon Task Configurations\nStandard Build Pipeline\n{\n  \"$schema\": \"https://turborepo.dev/schema.v2.json\",\n  \"tasks\": {\n    \"build\": {\n      \"dependsOn\": [\"^build\"],\n      \"outputs\": [\"dist/**\", \".next/**\", \"!.next/cache/**\"]\n    },\n    \"dev\": {\n      \"cache\": false,\n      \"persistent\": true\n    }\n  }\n}\n\n\nAdd a transit task if you have tasks that need parallel execution with cache invalidation (see below).\n\nDev Task with ^dev Pattern (for turbo watch)\n\nA dev task with dependsOn: [\"^dev\"] and persistent: false in root turbo.json may look unusual but is correct for turbo watch workflows:\n\n// Root turbo.json\n{\n  \"tasks\": {\n    \"dev\": {\n      \"dependsOn\": [\"^dev\"],\n      \"cache\": false,\n      \"persistent\": false  // Packages have one-shot dev scripts\n    }\n  }\n}\n\n// Package turbo.json (apps/web/turbo.json)\n{\n  \"extends\": [\"//\"],\n  \"tasks\": {\n    \"dev\": {\n      \"persistent\": true  // Apps run long-running dev servers\n    }\n  }\n}\n\n\nWhy this works:\n\nPackages (e.g., @acme/db, @acme/validators) have \"dev\": \"tsc\" — one-shot type generation that completes quickly\nApps override with persistent: true for actual dev servers (Next.js, etc.)\nturbo watch re-runs the one-shot package dev scripts when source files change, keeping types in sync\n\nIntended usage: Run turbo watch dev (not turbo run dev). Watch mode re-executes one-shot tasks on file changes while keeping persistent tasks running.\n\nAlternative pattern: Use a separate task name like prepare or generate for one-shot dependency builds to make the intent clearer:\n\n{\n  \"tasks\": {\n    \"prepare\": {\n      \"dependsOn\": [\"^prepare\"],\n      \"outputs\": [\"dist/**\"]\n    },\n    \"dev\": {\n      \"dependsOn\": [\"prepare\"],\n      \"cache\": false,\n      \"persistent\": true\n    }\n  }\n}\n\nTransit Nodes for Parallel Tasks with Cache Invalidation\n\nSome tasks can run in parallel (don't need built output from dependencies) but must invalidate cache when dependency source code changes.\n\nThe problem with dependsOn: [\"^taskname\"]:\n\nForces sequential execution (slow)\n\nThe problem with dependsOn: [] (no dependencies):\n\nAllows parallel execution (fast)\nBut cache is INCORRECT - changing dependency source won't invalidate cache\n\nTransit Nodes solve both:\n\n{\n  \"tasks\": {\n    \"transit\": { \"dependsOn\": [\"^transit\"] },\n    \"my-task\": { \"dependsOn\": [\"transit\"] }\n  }\n}\n\n\nThe transit task creates dependency relationships without matching any actual script, so tasks run in parallel with correct cache invalidation.\n\nHow to identify tasks that need this pattern: Look for tasks that read source files from dependencies but don't need their build outputs.\n\nWith Environment Variables\n{\n  \"globalEnv\": [\"NODE_ENV\"],\n  \"globalDependencies\": [\".env\"],\n  \"tasks\": {\n    \"build\": {\n      \"dependsOn\": [\"^build\"],\n      \"outputs\": [\"dist/**\"],\n      \"env\": [\"API_URL\", \"DATABASE_URL\"]\n    }\n  }\n}\n\nReference Index\nConfiguration\nFile\tPurpose\nconfiguration/README.md\tturbo.json overview, Package Configurations\nconfiguration/tasks.md\tdependsOn, outputs, inputs, env, cache, persistent\nconfiguration/global-options.md\tglobalEnv, globalDependencies, cacheDir, daemon, envMode\nconfiguration/gotchas.md\tCommon configuration mistakes\nCaching\nFile\tPurpose\ncaching/README.md\tHow caching works, hash inputs\ncaching/remote-cache.md\tVercel Remote Cache, self-hosted, login/link\ncaching/gotchas.md\tDebugging cache misses, --summarize, --dry\nEnvironment Variables\nFile\tPurpose\nenvironment/README.md\tenv, globalEnv, passThroughEnv\nenvironment/modes.md\tStrict vs Loose mode, framework inference\nenvironment/gotchas.md\t.env files, CI issues\nFiltering\nFile\tPurpose\nfiltering/README.md\t--filter syntax overview\nfiltering/patterns.md\tCommon filter patterns\nCI/CD\nFile\tPurpose\nci/README.md\tGeneral CI principles\nci/github-actions.md\tComplete GitHub Actions setup\nci/vercel.md\tVercel deployment, turbo-ignore\nci/patterns.md\t--affected, caching strategies\nCLI\nFile\tPurpose\ncli/README.md\tturbo run basics\ncli/commands.md\tturbo run flags, turbo-ignore, other commands\nBest Practices\nFile\tPurpose\nbest-practices/README.md\tMonorepo best practices overview\nbest-practices/structure.md\tRepository structure, workspace config, TypeScript/ESLint setup\nbest-practices/packages.md\tCreating internal packages, JIT vs Compiled, exports\nbest-practices/dependencies.md\tDependency management, installing, version sync\nWatch Mode\nFile\tPurpose\nwatch/README.md\tturbo watch, interruptible tasks, dev workflows\nBoundaries (Experimental)\nFile\tPurpose\nboundaries/README.md\tEnforce package isolation, tag-based dependency rules\nSource Documentation\n\nThis skill is based on the official Turborepo documentation at:\n\nSource: docs/site/content/docs/ in the Turborepo repository\nLive: https://turborepo.dev/docs"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/wpank/turborepo",
    "publisherUrl": "https://clawhub.ai/wpank/turborepo",
    "owner": "wpank",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/turborepo",
    "downloadUrl": "https://openagent3.xyz/downloads/turborepo",
    "agentUrl": "https://openagent3.xyz/skills/turborepo/agent",
    "manifestUrl": "https://openagent3.xyz/skills/turborepo/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/turborepo/agent.md"
  }
}