vercel/turborepo
Overview
This skill provides practical guidance for configuring and optimizing Turborepo in JavaScript/TypeScript monorepos. It focuses on correct task placement, caching, filtering, CI integration, and avoiding common anti-patterns to preserve parallelism and cache efficiency. Use it to structure package tasks, debug cache issues, and enforce boundaries across apps and internal packages.
How this skill works
The skill inspects turbo.json, package.json scripts, task pipelines (dependsOn, outputs, inputs), cache configuration (local and remote), filter/affected flags, and environment variable declarations. It identifies anti-patterns (root tasks, shortcut turbo usage, manual prebuilds), suggests package-level task placement and package-specific turbo.json overrides, and offers decisions for CI and watch/dev workflows.
When to use it
- Setting up or refactoring task scripts and pipelines in a monorepo
- Configuring caching, remote cache, or debugging cache misses
- Running only changed or dependent packages using --affected or --filter
- Optimizing CI to skip unnecessary builds and use remote cache
- Creating or structuring internal packages and enforcing boundaries
Best practices
- Always define tasks in each package and register them in root turbo.json; root package.json should only delegate with turbo run
- Use "turbo run" in package scripts and CI; reserve the shorthand turbo <task> for interactive use only
- Declare outputs for file-producing tasks to enable cache restores (e.g., dist/**, .next/**)
- Prefer dependsOn patterns (e.g., ^build) and workspace dependencies instead of manual prebuild scripts
- Use package-level turbo.json for package-specific overrides and keep root turbo.json as the base configuration
- Avoid globalDependencies that are too broad; move task-specific inputs and env into task-level config when needed
Example use cases
- You want CI to build only changed packages and their dependents: use turbo run build --affected and configure remote cache
- You see cache misses for a build: ensure outputs are declared, verify env is listed in task inputs, and use --summarize to debug hashes
- You need parallelized linting and tests across packages: put lint/test scripts in each package and register tasks instead of chaining in root
- You must enforce architecture rules: tag packages and use turbo boundaries to detect import violations
- You need to override a task for one package: add a package-level turbo.json that extends the root config
FAQ
Package tasks let Turborepo build a dependency graph and run tasks in parallel per-package; root scripts that run package logic block parallelization and cache benefits.
When should I use --affected vs --filter?
--affected is the recommended way to run changed packages plus dependents automatically. Use --filter for name or path-based selections or advanced patterns.