Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Configure and optimize Turborepo monorepo build pipelines with correct task structure, caching, and CI setup.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
SKILL.md
1---2name: turborepo3description: |4Turborepo monorepo build system guidance. Triggers on: turbo.json, task pipelines,5dependsOn, caching, remote cache, the "turbo" CLI, --filter, --affected, CI optimization, environment6variables, internal packages, monorepo structure/best practices, and boundaries.78Use when user: configures tasks/workflows/pipelines, creates packages, sets up9monorepo, shares code between apps, runs changed/affected packages, debugs cache,10or has apps/packages directories.11metadata:12version: 2.10.3-canary.413---1415# Turborepo Skill1617Build system for JavaScript/TypeScript monorepos. Turborepo caches task outputs and runs tasks in parallel based on dependency graph.1819## IMPORTANT: Package Tasks, Not Root Tasks2021**Prefer package tasks over Root Tasks.**2223When creating tasks/scripts/pipelines, you MUST default to package tasks:24251. Add the script to each relevant package's `package.json`262. Register the task in root `turbo.json`273. Root `package.json` only delegates via `turbo run <task>`2829**DO NOT** put task logic in root `package.json` when it can live in packages. This defeats Turborepo's parallelization.3031```json32// DO THIS: Scripts in each package33// apps/web/package.json34{ "scripts": { "build": "next build", "lint": "eslint .", "test": "vitest" } }3536// apps/api/package.json37{ "scripts": { "build": "tsc", "lint": "eslint .", "test": "vitest" } }3839// packages/ui/package.json40{ "scripts": { "build": "tsc", "lint": "eslint .", "test": "vitest" } }41```4243```json44// turbo.json - register tasks45{46"tasks": {47"build": { "dependsOn": ["^build"], "outputs": ["dist/**"] },48"lint": {},49"test": { "dependsOn": ["build"] }50}51}52```5354```json55// Root package.json - ONLY delegates, no task logic56{57"scripts": {58"build": "turbo run build",59"lint": "turbo run lint",60"test": "turbo run test"61}62}63```6465```json66// DO NOT DO THIS - defeats parallelization67// Root package.json68{69"scripts": {70"build": "cd apps/web && next build && cd ../api && tsc",71"lint": "eslint apps/ packages/",72"test": "vitest"73}74}75```7677Root Tasks (`//#taskname`) are ONLY for tasks that truly cannot exist in packages, such as Vitest Projects' `//#test`, repo-wide release scripts, or tooling that does not invoke `turbo` itself.7879## Secondary Rule: `turbo run` vs `turbo`8081**Always use `turbo run` when the command is written into code:**8283```json84// package.json - ALWAYS "turbo run"85{86"scripts": {87"build": "turbo run build"88}89}90```9192```yaml93# CI workflows - ALWAYS "turbo run"94- run: turbo run build --affected95```9697**The 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.9899## Quick Decision Trees100101### "I need to configure a task"102103```104Configure a task?105├─ Define task dependencies → references/configuration/tasks.md106├─ Lint/check-types (parallel + caching) → Use Transit Nodes pattern (see below)107├─ Specify build outputs → references/configuration/tasks.md#outputs108├─ Handle environment variables → references/environment/RULE.md109├─ Set up dev/watch tasks → references/configuration/tasks.md#persistent110├─ Package-specific config → references/configuration/RULE.md#package-configurations111└─ Global settings (cacheDir, daemon) → references/configuration/global-options.md112```113114### "My cache isn't working"115116```117Cache problems?118├─ Tasks run but outputs not restored → Missing `outputs` key119├─ Cache misses unexpectedly → references/caching/gotchas.md120├─ Need to debug hash inputs → Use --summarize or --dry121├─ Want to skip cache entirely → Use --force or cache: false122├─ Remote cache not working → references/caching/remote-cache.md123└─ Environment causing misses → references/environment/gotchas.md124```125126### "I want to run only changed packages"127128```129Run only what changed?130├─ Changed packages + dependents (RECOMMENDED) → turbo run build --affected131├─ Custom base branch → --affected --affected-base=origin/develop132├─ Manual git comparison → --filter=...[origin/main]133└─ See all filter options → references/filtering/RULE.md134```135136**`--affected` is the primary way to run only changed packages.** It automatically compares against the default branch and includes dependents.137138### "I want to filter packages"139140```141Filter packages?142├─ Only changed packages → --affected (see above)143├─ By package name → --filter=web144├─ By directory → --filter=./apps/*145├─ Package + dependencies → --filter=web...146├─ Package + dependents → --filter=...web147└─ Complex combinations → references/filtering/patterns.md148```149150### "Environment variables aren't working"151152```153Environment issues?154├─ Vars not available at runtime → Strict mode filtering (default)155├─ Cache hits with wrong env → Var not in `env` key156├─ .env changes not causing rebuilds → .env not in `inputs`157├─ CI variables missing → references/environment/gotchas.md158└─ Framework vars (NEXT_PUBLIC_*) → Auto-included via inference159```160161### "I need to set up CI"162163```164CI setup?165├─ GitHub Actions → references/ci/github-actions.md166├─ Vercel deployment → references/ci/vercel.md167├─ Remote cache in CI → references/caching/remote-cache.md168├─ Only build changed packages → --affected flag169├─ Skip unnecessary builds → turbo-ignore (references/cli/commands.md)170└─ Skip container setup when no changes → turbo-ignore171```172173### "I want to watch for changes during development"174175```176Watch mode?177├─ Re-run tasks on change → turbo watch (references/watch/RULE.md)178├─ Dev servers with dependencies → Use `with` key (references/configuration/tasks.md#with)179├─ Restart dev server on dep change → Use `interruptible: true`180└─ Persistent dev tasks → Use `persistent: true`181```182183### "I need to create/structure a package"184185```186Package creation/structure?187├─ Create an internal package → references/best-practices/packages.md188├─ Repository structure → references/best-practices/structure.md189├─ Dependency management → references/best-practices/dependencies.md190├─ Best practices overview → references/best-practices/RULE.md191├─ JIT vs Compiled packages → references/best-practices/packages.md#compilation-strategies192└─ Sharing code between apps → references/best-practices/RULE.md#package-types193```194195### "How should I structure my monorepo?"196197```198Monorepo structure?199├─ Standard layout (apps/, packages/) → references/best-practices/RULE.md200├─ Package types (apps vs libraries) → references/best-practices/RULE.md#package-types201├─ Creating internal packages → references/best-practices/packages.md202├─ TypeScript configuration → references/best-practices/structure.md#typescript-configuration203├─ ESLint configuration → references/best-practices/structure.md#eslint-configuration204├─ Dependency management → references/best-practices/dependencies.md205└─ Enforce package boundaries → references/boundaries/RULE.md206```207208### "I want to enforce architectural boundaries"209210```211Enforce boundaries?212├─ Check for violations → turbo boundaries213├─ Tag packages → references/boundaries/RULE.md#tags214├─ Restrict which packages can import others → references/boundaries/RULE.md#rule-types215└─ Prevent cross-package file imports → references/boundaries/RULE.md216```217218## Critical Anti-Patterns219220### Using `turbo` Shorthand in Code221222**`turbo run` is recommended in package.json scripts and CI pipelines.** The shorthand `turbo <task>` is intended for interactive terminal use.223224```json225// WRONG - using shorthand in package.json226{227"scripts": {228"build": "turbo build",229"dev": "turbo dev"230}231}232233// CORRECT234{235"scripts": {236"build": "turbo run build",237"dev": "turbo run dev"238}239}240```241242```yaml243# WRONG - using shorthand in CI244- run: turbo build --affected245246# CORRECT247- run: turbo run build --affected248```249250### Root Scripts Bypassing Turbo251252Root `package.json` scripts MUST delegate to `turbo run`, not run tasks directly.253254```json255// WRONG - bypasses turbo entirely256{257"scripts": {258"build": "bun build",259"dev": "bun dev"260}261}262263// CORRECT - delegates to turbo264{265"scripts": {266"build": "turbo run build",267"dev": "turbo run dev"268}269}270```271272### Using `&&` to Chain Turbo Tasks273274Don't chain turbo tasks with `&&`. Let turbo orchestrate.275276```json277// WRONG - turbo task not using turbo run278{279"scripts": {280"changeset:publish": "bun build && changeset publish"281}282}283284// CORRECT285{286"scripts": {287"changeset:publish": "turbo run build && changeset publish"288}289}290```291292### `prebuild` Scripts That Manually Build Dependencies293294Scripts like `prebuild` that manually build other packages bypass Turborepo's dependency graph.295296```json297// WRONG - manually building dependencies298{299"scripts": {300"prebuild": "cd ../../packages/types && bun run build && cd ../utils && bun run build",301"build": "next build"302}303}304```305306**However, the fix depends on whether workspace dependencies are declared:**3073081. **If dependencies ARE declared** (e.g., `"@repo/types": "workspace:*"` in package.json), remove the `prebuild` script. Turbo's `dependsOn: ["^build"]` handles this automatically.3093102. **If dependencies are NOT declared**, the `prebuild` exists because `^build` won't trigger without a dependency relationship. The fix is to:311- Add the dependency to package.json: `"@repo/types": "workspace:*"`312- Then remove the `prebuild` script313314```json315// CORRECT - declare dependency, let turbo handle build order316// package.json317{318"dependencies": {319"@repo/types": "workspace:*",320"@repo/utils": "workspace:*"321},322"scripts": {323"build": "next build"324}325}326327// turbo.json328{329"tasks": {330"build": {331"dependsOn": ["^build"]332}333}334}335```336337**Key insight:** `^build` only runs build in packages listed as dependencies. No dependency declaration = no automatic build ordering.338339### Overly Broad `globalDependencies`340341`globalDependencies` affects ALL tasks in ALL packages via the **global hash** — tasks cannot opt out of specific files, even with negation globs in `inputs`. Be specific.342343```json344// WRONG - heavy hammer, affects all hashes345{346"globalDependencies": ["**/.env.*local"]347}348349// BETTER - move to task-level inputs350{351"globalDependencies": [".env"],352"tasks": {353"build": {354"inputs": ["$TURBO_DEFAULT$", ".env*"],355"outputs": ["dist/**"]356}357}358}359```360361With `futureFlags.globalConfiguration`, this problem is reduced because `global.inputs` files are folded into each task's inputs (not the global hash). Tasks can exclude specific files:362363```json364// BEST - global.inputs with per-task exclusion365{366"futureFlags": { "globalConfiguration": true },367"global": {368"inputs": [".env"]369},370"tasks": {371"build": { "outputs": ["dist/**"] },372"lint": {373"inputs": ["$TURBO_DEFAULT$", "!$TURBO_ROOT$/.env"]374}375}376}377```378379### Repetitive Task Configuration380381Look for repeated configuration across tasks that can be collapsed. Turborepo supports shared configuration patterns.382383```json384// WRONG - repetitive env and inputs across tasks385{386"tasks": {387"build": {388"env": ["API_URL", "DATABASE_URL"],389"inputs": ["$TURBO_DEFAULT$", ".env*"]390},391"test": {392"env": ["API_URL", "DATABASE_URL"],393"inputs": ["$TURBO_DEFAULT$", ".env*"]394},395"dev": {396"env": ["API_URL", "DATABASE_URL"],397"inputs": ["$TURBO_DEFAULT$", ".env*"],398"cache": false,399"persistent": true400}401}402}403404// BETTER - use globalEnv and globalDependencies for shared config405{406"globalEnv": ["API_URL", "DATABASE_URL"],407"globalDependencies": [".env*"],408"tasks": {409"build": {},410"test": {},411"dev": {412"cache": false,413"persistent": true414}415}416}417```418419**When to use global vs task-level:**420421- `globalEnv` / `globalDependencies` - affects ALL tasks, use for truly shared config422- Task-level `env` / `inputs` - use when only specific tasks need it423424### NOT an Anti-Pattern: Large `env` Arrays425426A 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.427428### Using `--parallel` Flag429430The `--parallel` flag bypasses Turborepo's dependency graph. If tasks need parallel execution, configure `dependsOn` correctly instead.431432```bash433# WRONG - bypasses dependency graph434turbo run lint --parallel435436# CORRECT - configure tasks to allow parallel execution437# In turbo.json, set dependsOn appropriately (or use transit nodes)438turbo run lint439```440441### Package-Specific Task Overrides in Root turbo.json442443When multiple packages need different task configurations, use **Package Configurations** (`turbo.json` in each package) instead of cluttering root `turbo.json` with `package#task` overrides.444445```json446// WRONG - root turbo.json with many package-specific overrides447{448"tasks": {449"test": { "dependsOn": ["build"] },450"@repo/web#test": { "outputs": ["coverage/**"] },451"@repo/api#test": { "outputs": ["coverage/**"] },452"@repo/utils#test": { "outputs": [] },453"@repo/cli#test": { "outputs": [] },454"@repo/core#test": { "outputs": [] }455}456}457458// CORRECT - use Package Configurations459// Root turbo.json - base config only460{461"tasks": {462"test": { "dependsOn": ["build"] }463}464}465466// packages/web/turbo.json - package-specific override467{468"extends": ["//"],469"tasks": {470"test": { "outputs": ["coverage/**"] }471}472}473474// packages/api/turbo.json475{476"extends": ["//"],477"tasks": {478"test": { "outputs": ["coverage/**"] }479}480}481```482483**Benefits of Package Configurations:**484485- Keeps configuration close to the code it affects486- Root turbo.json stays clean and focused on base patterns487- Easier to understand what's special about each package488- Works with `$TURBO_EXTENDS$` to inherit + extend arrays489490**When to use `package#task` in root:**491492- Single package needs a unique dependency (e.g., `"deploy": { "dependsOn": ["web#build"] }`)493- Temporary override while migrating494495See `references/configuration/RULE.md#package-configurations` for full details.496497### Using `../` to Traverse Out of Package in `inputs`498499Don't use relative paths like `../` to reference files outside the package. Use `$TURBO_ROOT$` instead.500501```json502// WRONG - traversing out of package503{504"tasks": {505"build": {506"inputs": ["$TURBO_DEFAULT$", "../shared-config.json"]507}508}509}510511// CORRECT - use $TURBO_ROOT$ for repo root512{513"tasks": {514"build": {515"inputs": ["$TURBO_DEFAULT$", "$TURBO_ROOT$/shared-config.json"]516}517}518}519```520521### Missing `outputs` for File-Producing Tasks522523**Before flagging missing `outputs`, check what the task actually produces:**5245251. Read the package's script (e.g., `"build": "tsc"`, `"test": "vitest"`)5262. Determine if it writes files to disk or only outputs to stdout5273. Only flag if the task produces files that should be cached528529```json530// WRONG: build produces files but they're not cached531{532"tasks": {533"build": {534"dependsOn": ["^build"]535}536}537}538539// CORRECT: build outputs are cached540{541"tasks": {542"build": {543"dependsOn": ["^build"],544"outputs": ["dist/**"]545}546}547}548```549550Common outputs by framework:551552- Next.js: `[".next/**", "!.next/cache/**", "!.next/dev/**"]`553- Vite/Rollup: `["dist/**"]`554- tsc: `["dist/**"]` or custom `outDir`555556**TypeScript `--noEmit` can still produce cache files:**557558When `incremental: true` in tsconfig.json, `tsc --noEmit` writes `.tsbuildinfo` files even without emitting JS. Check the tsconfig before assuming no outputs:559560```json561// If tsconfig has incremental: true, tsc --noEmit produces cache files562{563"tasks": {564"typecheck": {565"outputs": ["node_modules/.cache/tsbuildinfo.json"] // or wherever tsBuildInfoFile points566}567}568}569```570571To determine correct outputs for TypeScript tasks:5725731. Check if `incremental` or `composite` is enabled in tsconfig5742. Check `tsBuildInfoFile` for custom cache location (default: alongside `outDir` or in project root)5753. If no incremental mode, `tsc --noEmit` produces no files576577### `^build` vs `build` Confusion578579```json580{581"tasks": {582// ^build = run build in DEPENDENCIES first (other packages this one imports)583"build": {584"dependsOn": ["^build"]585},586// build (no ^) = run build in SAME PACKAGE first587"test": {588"dependsOn": ["build"]589},590// pkg#task = specific package's task591"deploy": {592"dependsOn": ["web#build"]593}594}595}596```597598### Environment Variables Not Hashed599600```json601// WRONG: API_URL changes won't cause rebuilds602{603"tasks": {604"build": {605"outputs": ["dist/**"]606}607}608}609610// CORRECT: API_URL changes invalidate cache611{612"tasks": {613"build": {614"outputs": ["dist/**"],615"env": ["API_URL", "API_KEY"]616}617}618}619```620621### `.env` Files Not in Inputs622623Turbo does NOT load `.env` files - your framework does. But Turbo needs to know about changes:624625```json626// WRONG: .env changes don't invalidate cache627{628"tasks": {629"build": {630"env": ["API_URL"]631}632}633}634635// CORRECT: .env file changes invalidate cache636{637"tasks": {638"build": {639"env": ["API_URL"],640"inputs": ["$TURBO_DEFAULT$", ".env", ".env.*"]641}642}643}644```645646### Root `.env` File in Monorepo647648A `.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.649650```651// WRONG - root .env affects all packages implicitly652my-monorepo/653├── .env # Which packages use this?654├── apps/655│ ├── web/656│ └── api/657└── packages/658659// CORRECT - .env files in packages that need them660my-monorepo/661├── apps/662│ ├── web/663│ │ └── .env # Clear: web needs DATABASE_URL664│ └── api/665│ └── .env # Clear: api needs API_KEY666└── packages/667```668669**Problems with root `.env`:**670671- Unclear which packages consume which variables672- All packages get all variables (even ones they don't need)673- Cache invalidation is coarse-grained (root .env change invalidates everything)674- Security risk: packages may accidentally access sensitive vars meant for others675- Bad habits start small — starter templates should model correct patterns676677**If you must share variables**, use `globalEnv` to be explicit about what's shared, and document why.678679### Strict Mode Filtering CI Variables680681By default, Turborepo filters environment variables to only those in `env`/`globalEnv`. CI variables may be missing:682683```json684// If CI scripts need GITHUB_TOKEN but it's not in env:685{686"globalPassThroughEnv": ["GITHUB_TOKEN", "CI"],687"tasks": { ... }688}689```690691Or use `--env-mode=loose` (not recommended for production).692693### Shared Code in Apps (Should Be a Package)694695```696// WRONG: Shared code inside an app697apps/698web/699shared/ # This breaks monorepo principles!700utils.ts701702// CORRECT: Extract to a package703packages/704utils/705src/utils.ts706```707708### Accessing Files Across Package Boundaries709710```typescript711// WRONG: Reaching into another package's internals712import { Button } from "../../packages/ui/src/button";713714// CORRECT: Install and import properly715import { Button } from "@repo/ui/button";716```717718### Too Many Root Dependencies719720```json721// WRONG: App dependencies in root722{723"dependencies": {724"react": "^18",725"next": "^14"726}727}728729// CORRECT: Only repo tools in root730{731"devDependencies": {732"turbo": "latest"733}734}735```736737## Common Task Configurations738739### Standard Build Pipeline740741```json742{743"$schema": "https://v2-10-3-canary-4.turborepo.dev/schema.json",744"tasks": {745"build": {746"dependsOn": ["^build"],747"outputs": ["dist/**", ".next/**", "!.next/cache/**", "!.next/dev/**"]748},749"dev": {750"cache": false,751"persistent": true752}753}754}755```756757Add a `transit` task if you have tasks that need parallel execution with cache invalidation (see below).758759### Dev Task with `^dev` Pattern (for `turbo watch`)760761A `dev` task with `dependsOn: ["^dev"]` and `persistent: false` in root turbo.json may look unusual but is **correct for `turbo watch` workflows**:762763```json764// Root turbo.json765{766"tasks": {767"dev": {768"dependsOn": ["^dev"],769"cache": false,770"persistent": false // Packages have one-shot dev scripts771}772}773}774775// Package turbo.json (apps/web/turbo.json)776{777"extends": ["//"],778"tasks": {779"dev": {780"persistent": true // Apps run long-running dev servers781}782}783}784```785786**Why this works:**787788- **Packages** (e.g., `@acme/db`, `@acme/validators`) have `"dev": "tsc"` — one-shot type generation that completes quickly789- **Apps** override with `persistent: true` for actual dev servers (Next.js, etc.)790- **`turbo watch`** re-runs the one-shot package `dev` scripts when source files change, keeping types in sync791792**Intended usage:** Run `turbo watch dev` (not `turbo run dev`). Watch mode re-executes one-shot tasks on file changes while keeping persistent tasks running.793794**Alternative pattern:** Use a separate task name like `prepare` or `generate` for one-shot dependency builds to make the intent clearer:795796```json797{798"tasks": {799"prepare": {800"dependsOn": ["^prepare"],801"outputs": ["dist/**"]802},803"dev": {804"dependsOn": ["prepare"],805"cache": false,806"persistent": true807}808}809}810```811812### Transit Nodes for Parallel Tasks with Cache Invalidation813814Some tasks can run in parallel (don't need built output from dependencies) but must invalidate cache when dependency source code changes.815816**The problem with `dependsOn: ["^taskname"]`:**817818- Forces sequential execution (slow)819820**The problem with `dependsOn: []` (no dependencies):**821822- Allows parallel execution (fast)823- But cache is INCORRECT - changing dependency source won't invalidate cache824825**Transit Nodes solve both:**826827```json828{829"tasks": {830"transit": { "dependsOn": ["^transit"] },831"my-task": { "dependsOn": ["transit"] }832}833}834```835836The `transit` task creates dependency relationships without matching any actual script, so tasks run in parallel with correct cache invalidation.837838**How to identify tasks that need this pattern:** Look for tasks that read source files from dependencies but don't need their build outputs.839840### With Environment Variables841842```json843{844"globalEnv": ["NODE_ENV"],845"globalDependencies": [".env"],846"tasks": {847"build": {848"dependsOn": ["^build"],849"outputs": ["dist/**"],850"env": ["API_URL", "DATABASE_URL"]851}852}853}854```855856With `futureFlags.globalConfiguration`, the same config moves global settings under `global` — and `.env` becomes a per-task input instead of a global hash input:857858```json859{860"futureFlags": { "globalConfiguration": true },861"global": {862"env": ["NODE_ENV"],863"inputs": [".env"]864},865"tasks": {866"build": {867"dependsOn": ["^build"],868"outputs": ["dist/**"],869"env": ["API_URL", "DATABASE_URL"]870}871}872}873```874875## Reference Index876877### Configuration878879| File | Purpose |880| ------------------------------------------------------------------------------- | ------------------------------------------------------------------------- |881| [configuration/RULE.md](./references/configuration/RULE.md) | turbo.json overview, Package Configurations |882| [configuration/tasks.md](./references/configuration/tasks.md) | dependsOn, outputs, inputs, env, cache, persistent |883| [configuration/global-options.md](./references/configuration/global-options.md) | globalEnv, globalDependencies, global key, futureFlags, cacheDir, envMode |884| [configuration/gotchas.md](./references/configuration/gotchas.md) | Common configuration mistakes |885886### Caching887888| File | Purpose |889| --------------------------------------------------------------- | -------------------------------------------- |890| [caching/RULE.md](./references/caching/RULE.md) | How caching works, hash inputs |891| [caching/remote-cache.md](./references/caching/remote-cache.md) | Vercel Remote Cache, self-hosted, login/link |892| [caching/gotchas.md](./references/caching/gotchas.md) | Debugging cache misses, --summarize, --dry |893894### Environment Variables895896| File | Purpose |897| ------------------------------------------------------------- | ----------------------------------------- |898| [environment/RULE.md](./references/environment/RULE.md) | env, globalEnv, passThroughEnv |899| [environment/modes.md](./references/environment/modes.md) | Strict vs Loose mode, framework inference |900| [environment/gotchas.md](./references/environment/gotchas.md) | .env files, CI issues |901902### Filtering903904| File | Purpose |905| ----------------------------------------------------------- | ------------------------ |906| [filtering/RULE.md](./references/filtering/RULE.md) | --filter syntax overview |907| [filtering/patterns.md](./references/filtering/patterns.md) | Common filter patterns |908909### CI/CD910911| File | Purpose |912| --------------------------------------------------------- | ------------------------------- |913| [ci/RULE.md](./references/ci/RULE.md) | General CI principles |914| [ci/github-actions.md](./references/ci/github-actions.md) | Complete GitHub Actions setup |915| [ci/vercel.md](./references/ci/vercel.md) | Vercel deployment, turbo-ignore |916| [ci/patterns.md](./references/ci/patterns.md) | --affected, caching strategies |917918### CLI919920| File | Purpose |921| ----------------------------------------------- | --------------------------------------------- |922| [cli/RULE.md](./references/cli/RULE.md) | turbo run basics |923| [cli/commands.md](./references/cli/commands.md) | turbo run flags, turbo-ignore, other commands |924925### Best Practices926927| File | Purpose |928| ----------------------------------------------------------------------------- | --------------------------------------------------------------- |929| [best-practices/RULE.md](./references/best-practices/RULE.md) | Monorepo best practices overview |930| [best-practices/structure.md](./references/best-practices/structure.md) | Repository structure, workspace config, TypeScript/ESLint setup |931| [best-practices/packages.md](./references/best-practices/packages.md) | Creating internal packages, JIT vs Compiled, exports |932| [best-practices/dependencies.md](./references/best-practices/dependencies.md) | Dependency management, installing, version sync |933934### Watch Mode935936| File | Purpose |937| ------------------------------------------- | ----------------------------------------------- |938| [watch/RULE.md](./references/watch/RULE.md) | turbo watch, interruptible tasks, dev workflows |939940### Boundaries (Experimental)941942| File | Purpose |943| ----------------------------------------------------- | ----------------------------------------------------- |944| [boundaries/RULE.md](./references/boundaries/RULE.md) | Enforce package isolation, tag-based dependency rules |945946## Source Documentation947948This skill is based on the official Turborepo documentation at:949950- Source: `apps/docs/content/docs/` in the Turborepo repository951- Live: https://turborepo.dev/docs952