
Turborepo Monorepo
- 1.8k installs
- 311 repo stars
- Updated June 22, 2026
- giuseppe-trisciuoglio/developer-kit
Turborepo monorepo setup guide.
About
The turborepo-monorepo skill covers Turborepo management for TypeScript JavaScript monorepos including workspace creation via pnpm create turbo, turbo.json task dependencies and outputs, Next.js NestJS setup, Vitest Jest pipelines, GitHub Actions GitLab CI, Vercel Remote Cache, build tuning, and migration from other monorepo tools. Instructions include minimal configs debugging cache misses and optimizing hit ratios. Developers invoke when initializing monorepos wiring task graphs implementing remote caching or troubleshooting dependency chains across packages in Turborepo workspaces for faster CI and local builds. pnpm create turbo workspace scaffolding. turbo.json tasks outputs dependencies. Next.js NestJS Vitest Jest monorepo setup. Vercel Remote Cache and CI workflows. Debug cache misses and task graphs. Turborepo monorepo setup guide. User asks Turborepo tasks or remote cache.
- pnpm create turbo workspace scaffolding.
- turbo.json tasks outputs dependencies.
- Next.js NestJS Vitest Jest monorepo setup.
- Vercel Remote Cache and CI workflows.
- Debug cache misses and task graphs.
Turborepo Monorepo by the numbers
- 1,786 all-time installs (skills.sh)
- +86 installs in the week ending Jul 28, 2026 (Skillselion tracking)
- Ranked #116 of 1,453 DevOps & CI/CD skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Jul 28, 2026 (Skillselion catalog sync)
turborepo-monorepo capabilities & compatibility
- Capabilities
- workspace setup · remote cache
- Use cases
- ci cd · devops
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill turborepo-monorepoAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1.8k |
|---|---|
| repo stars | ★ 311 |
| Security audit | 3 / 3 scanners passed |
| Last updated | June 22, 2026 |
| Repository | giuseppe-trisciuoglio/developer-kit ↗ |
How configure turbo.json remote cache?
Configure Turborepo workspaces, turbo.json, Next.js/NestJS apps, tests, remote cache, and CI for TS monorepos.
Who is it for?
Teams adopting Turborepo.
Skip if: Single package apps.
When should I use this skill?
User asks Turborepo tasks or remote cache.
What you get
Monorepo with CI optimized builds.
- GitHub Actions CI workflow YAML
- Turborepo remote cache configuration
By the numbers
- CI job timeout-minutes set to 15 in the basic workflow example
- Uses pnpm version 9 and Node.js 20 in GitHub Actions setup steps
Files
Turborepo Monorepo
Overview
Provides guidance for Turborepo monorepo management: workspace creation, turbo.json task configuration, Next.js/NestJS integration, testing pipelines (Vitest/Jest), CI/CD setup, and build performance optimization.
When to Use
- Create or initialize Turborepo workspaces
- Configure
turbo.jsontasks with dependencies and outputs - Set up Next.js/NestJS apps in monorepo structure
- Configure Vitest/Jest test pipelines
- Build CI/CD workflows (GitHub Actions, GitLab CI)
- Implement remote caching with Vercel Remote Cache
- Optimize build times and cache hit ratios
- Debug task dependency or cache issues
- Migrate from other monorepo tools to Turborepo
Instructions
Workspace Creation
1. Create a new workspace:
pnpm create turbo@latest my-workspace
cd my-workspace2. Initialize in existing project:
pnpm add -D -w turbo3. Create turbo.json in root (minimal config):
{
"$schema": "https://turborepo.dev/schema.json",
"pipeline": {
"build": { "dependsOn": ["^build"], "outputs": ["dist/**", ".next/**"] },
"lint": { "outputs": [] },
"test": { "dependsOn": ["build"], "outputs": ["coverage/**"] }
}
}4. Add scripts to root package.json:
{ "scripts": { "build": "turbo run build", "dev": "turbo run dev", "lint": "turbo run lint", "test": "turbo run test", "clean": "turbo run clean" } }5. Validate task graph before CI:
turbo run build --dry-run --filter=... # Verify task execution orderTask Configuration
1. Configure tasks in turbo.json:
{ "pipeline": { "build": { "dependsOn": ["^build"], "outputs": ["dist/**"] }, "test": { "dependsOn": ["build"], "outputs": ["coverage/**"] }, "lint": { "outputs": [] } } }2. Run tasks:
turbo run build # All packages
turbo run lint test build # Multiple tasks
turbo run build --filter=web # Specific package3. Parallel type checking (use transit nodes to avoid cache issues):
{ "pipeline": { "transit": { "dependsOn": ["^transit"] }, "typecheck": { "dependsOn": ["transit"] } } }4. Validate before committing:
turbo run build --dry-run # Check task order and affected packagesFramework Integration
Next.js: outputs ".next/**" and env ["NEXT_PUBLIC_*"] - See references/nextjs-config.md
NestJS: outputs "dist/**", dev tasks with cache: false, persistent: true - See references/nestjs-config.md
Testing Setup
1. Vitest configuration:
{
"pipeline": {
"test": {
"outputs": [],
"inputs": ["$TURBO_DEFAULT$", "vitest.config.ts"]
},
"test:watch": {
"cache": false,
"persistent": true
}
}
}2. Run affected tests:
turbo run test --filter=[HEAD^]See references/testing-config.md for complete testing setup.
Package Configurations
1. Create package-specific turbo.json:
{
"extends": ["//"],
"tasks": {
"build": {
"outputs": ["$TURBO_EXTENDS$", ".next/**"]
}
}
}See references/package-configs.md for detailed package configuration patterns.
CI/CD Setup
1. GitHub Actions with validation checkpoints:
- name: Install dependencies
run: pnpm install
- name: Validate affected packages (dry-run)
run: pnpm turbo run build --filter=[HEAD^] --dry-run
# VALIDATE: Review output to confirm only expected packages will build
- name: Run tests
run: pnpm run test --filter=[HEAD^]
- name: Build affected packages
run: pnpm run build --filter=[HEAD^]
- name: Verify cache hits
run: pnpm turbo run build --filter=[HEAD^] --dry-run | grep "Cache"
# VALIDATE: Confirm cache hits for unchanged packages2. Remote cache setup:
# Login to Vercel
npx turbo login
# Link repository
npx turbo linkSee references/ci-cd.md for complete CI/CD setup examples.
Task Properties Reference
| Property | Description | Example |
|---|---|---|
dependsOn | Tasks that must complete first | ["^build"] - dependencies first |
outputs | Files/folders to cache | ["dist/**"] |
inputs | Files for cache hash | ["src/**/*.ts"] |
env | Environment variables affecting hash | ["DATABASE_URL"] |
cache | Enable/disable caching | true or false |
persistent | Long-running task | true for dev servers |
outputLogs | Log verbosity | "full", "new-only", "errors-only" |
Dependency Patterns
^task- Run task in dependencies first (topological order)task- Run task in same package firstpackage#task- Run specific package's task
Filter Syntax
| Filter | Description |
|---|---|
web | Only web package |
web... | web + all dependencies |
...web | web + all dependents |
...web... | web + deps + dependents |
[HEAD^] | Packages changed since last commit |
./apps/* | All packages in apps/ |
Best Practices
Performance Optimization
1. Use specific outputs - Only cache what's needed 2. Fine-tune inputs - Exclude files that don't affect output 3. Transit nodes - Enable parallel type checking 4. Remote cache - Share cache across team/CI 5. Package configurations - Customize per-package behavior
Caching Strategy
{
"pipeline": {
"build": {
"outputs": ["dist/**"],
"inputs": ["$TURBO_DEFAULT$", "!README.md", "!**/*.md"]
}
}
}Task Organization
- Independent tasks - No
dependsOn: lint, format, spellcheck - Build tasks -
dependsOn: ["^build"]: build, compile - Test tasks -
dependsOn: ["build"]: test, e2e - Dev tasks -
cache: false, persistent: true: dev, watch
Common Issues
Tasks not running in order
Problem: Tasks execute in wrong order
Solution: Check dependsOn configuration
{
"build": {
"dependsOn": ["^build"]
}
}Cache misses on unchanged files
Problem: Cache invalidating unexpectedly
Solution: Review globalDependencies and inputs
{
"globalDependencies": ["tsconfig.json"],
"pipeline": {
"build": {
"inputs": ["$TURBO_DEFAULT$", "!*.md"]
}
}
}Type errors after cache hit
Problem: TypeScript errors not caught due to cache
Solution: Use transit nodes for type checking
{
"transit": { "dependsOn": ["^transit"] },
"typecheck": { "dependsOn": ["transit"] }
}Examples
Example 1: Create New Workspace
Input: "Create a Turborepo with Next.js and NestJS"
pnpm create turbo@latest my-workspace
cd my-workspace
# Add Next.js app
pnpm add next react react-dom -F apps/web
# Add NestJS API
pnpm add @nestjs/core @nestjs/common -F apps/apiExample 2: Configure Testing Pipeline
Input: "Set up Vitest for all packages"
{
"pipeline": {
"test": {
"dependsOn": ["build"],
"outputs": ["coverage/**"],
"inputs": ["$TURBO_DEFAULT$", "vitest.config.ts"]
},
"test:watch": {
"cache": false,
"persistent": true
}
}
}Example 3: Run Affected Tests in CI
Input: "Only test changed packages in CI"
pnpm run test --filter=[HEAD^]Example 4: Debug Cache Issues
Input: "Why is my cache missing?"
# Dry run to see what would be executed
turbo run build --dry-run --filter=web
# Show hash inputs
turbo run build --force --filter=webConstraints and Warnings
- Node.js 18+ is required for Turborepo
- Package manager field required in root
package.json - Outputs must be specified for caching to work
- Persistent tasks cannot have dependents
- Windows: WSL or Git Bash recommended
- Remote cache requires Vercel account or self-hosted solution
- Large monorepos may need increased
concurrencysettings
Reference Files
For detailed guidance on specific topics, consult:
| Topic | Reference File |
|---|---|
| turbo.json template | references/turbo.json |
| Next.js integration | references/nextjs-config.md |
| NestJS integration | references/nestjs-config.md |
| Vitest/Jest/Playwright | references/testing-config.md |
| GitHub/CircleCI/GitLab CI | references/ci-cd.md |
| Package configurations | references/package-configs.md |
CI/CD con Turborepo
GitHub Actions
Basic workflow
name: CI
on:
push:
branches: [main]
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build-and-test:
name: Build and test
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
- name: Run lint
run: pnpm run lint --filter=[HEAD^]
- name: Run type check
run: pnpm run typecheck --filter=[HEAD^]
- name: Run tests
run: pnpm run test --filter=[HEAD^]
- name: Build
run: pnpm run build --filter=[HEAD^]Con Turborepo Remote Cache
name: CI
on:
push:
branches: [main]
pull_request:
jobs:
build-and-test:
runs-on: ubuntu-latest
# Output from turbo's `pack` command
outputs:
artifact-hash: ${{ steps.pack.outputs.hash }}
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
steps:
- uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
- name: Build & test
run: pnpm run build test
- name: Pack cache
id: pack
run: |
tar -czf cache.tar.gz .turbo/cache
echo "hash=$(sha256sum cache.tar.gz | cut -c1-10)" >> $GITHUB_OUTPUT
- name: Upload cache
uses: actions/cache/save@v4
with:
path: .turbo/cache
key: turbo-${{ runner.os }}-${{ steps.pack.outputs.hash }}Workflow con affected packages
name: Affected CI
on:
pull_request:
jobs:
affected:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
- name: Lint affected
run: pnpm run lint --filter=[HEAD^]
- name: Test affected
run: pnpm run test --filter=[HEAD^]
- name: Build affected
run: pnpm run build --filter=[HEAD^]CircleCI
version: 2.1
orbs:
node: circleci/node@5.1
executors:
node-executor:
docker:
- image: cimg/node:20.11
resource_class: medium
jobs:
build-and-test:
executor: node-executor
steps:
- checkout
- node/install-packages:
pkg-manager: pnpm
cache-version: v1
- run:
name: Lint affected
command: pnpm run lint --filter=[HEAD^]
- run:
name: Test affected
command: pnpm run test --filter=[HEAD^]
- run:
name: Build affected
command: pnpm run build --filter=[HEAD^]
workflows:
build-test:
jobs:
- build-and-test:
context:
- turbo-secretsGitLab CI
stages:
- validate
- test
- build
variables:
PNPM_VERSION: "9"
NODE_VERSION: "20"
TURBO_TOKEN: ${TURBO_TOKEN}
TURBO_TEAM: ${TURBO_TEAM}
.cache_config:
cache:
key:
files:
- pnpm-lock.yaml
paths:
- .pnpm-store
- node_modules
lint:
stage: validate
image: node:${NODE_VERSION}
extends: .cache_config
script:
- corepack enable
- corepack prepare pnpm@${PNPM_VERSION} --activate
- pnpm install --frozen-lockfile
- pnpm run lint --filter=[HEAD^]
test:
stage: test
image: node:${NODE_VERSION}
extends: .cache_config
script:
- corepack enable
- corepack prepare pnpm@${PNPM_VERSION} --activate
- pnpm install --frozen-lockfile
- pnpm run test --filter=[HEAD^]
build:
stage: build
image: node:${NODE_VERSION}
extends: .cache_config
script:
- corepack enable
- corepack prepare pnpm@${PNPM_VERSION} --activate
- pnpm install --frozen-lockfile
- pnpm run build --filter=[HEAD^]Deployment Pipeline
Deploy changed apps
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup pnpm and Node
uses: pnpm/action-setup@v4
with:
version: 9
- name: Install dependencies
run: pnpm install
- name: Build
run: pnpm run build --filter=[HEAD^]
- name: Deploy Next.js app
if: contains(steps.turbo.outputs.apps, 'web')
run: pnpm --filter web deploy
- name: Deploy NestJS API
if: contains(steps.turbo.outputs.apps, 'api')
run: pnpm --filter api deployBest Practices CI/CD
1. Usa sempre `--filter=[HEAD^]` nelle PR per testare solo i pacchetti modificati
2. Cache delle dipendenze per velocizzare il setup
3. Paralellizza i task dove possibile
4. Usa turbo-ignore per skipare le build inutili:
pnpm add -D -w turbo-ignore{
"scripts": {
"check": "turbo-ignore"
}
}5. Fallback cache locale se remote cache non è disponibile
6. Timeout appropriati per evitare job bloccati
7. Artifact caching tra jobs:
- name: Save build artifacts
uses: actions/upload-artifact@v4
with:
name: build
path: apps/*/dist
- name: Load build artifacts
uses: actions/download-artifact@v4
with:
name: buildTurbo in Docker
FROM node:20-alpine AS build
WORKDIR /app
# Setup pnpm
RUN corepack enable && corepack prepare pnpm@latest --activate
# Copy package files
COPY package.json pnpm-lock.yaml ./
COPY pnpm-workspace.yaml ./
# Install dependencies
RUN pnpm install --frozen-lockfile
# Copy source
COPY . .
# Build with turbo
RUN pnpm run build
# Production stage
FROM node:20-alpine AS prod
WORKDIR /app
COPY --from=build /app/apps/api/dist ./dist
COPY --from=build /app/apps/api/package.json ./
CMD ["node", "dist/main.js"]NestJS in Turborepo
Package Structure
apps/
api/
package.json
nest-cli.json
tsconfig.json
tsconfig.build.json
src/
main.ts
libs/
shared/
package.json
tsconfig.json
src/
index.tsapi/package.json
{
"name": "api",
"version": "0.0.0",
"private": true,
"scripts": {
"build": "nest build",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@nestjs/common": "^10.4.7",
"@nestjs/core": "^10.4.7",
"@nestjs/platform-express": "^10.4.7",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.1",
"shared": "*"
},
"devDependencies": {
"@nestjs/cli": "^10.4.7",
"@nestjs/schematics": "^10.2.3",
"@nestjs/testing": "^10.4.7",
"@types/express": "^5.0.0",
"@types/jest": "^29.5.14",
"@types/node": "^22.10.5",
"@typescript-eslint/eslint-plugin": "^8.19.1",
"@typescript-eslint/parser": "^8.19.1",
"eslint": "^9",
"jest": "^29.7.0",
"ts-jest": "^29.2.5",
"ts-loader": "^9.5.2",
"ts-node": "^10.9.2",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.7.2"
}
}turbo.json for NestJS
{
"$schema": "https://turborepo.dev/schema.json",
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
},
"start:dev": {
"cache": false,
"persistent": true
},
"test": {
"dependsOn": ["build"],
"outputs": ["coverage/**"],
"inputs": ["$TURBO_DEFAULT$", "jest.config.js"]
},
"lint": {
"outputs": []
},
"typecheck": {
"dependsOn": ["^build"],
"outputs": []
}
}
}nest-cli.json
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"deleteOutDir": true,
"webpack": false
}
}tsconfig.build.json
{
"extends": "./tsconfig.json",
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
}Workspace tsconfig paths
In root tsconfig.json:
{
"compilerOptions": {
"paths": {
"api/*": ["./apps/api/src/*"],
"shared/*": ["./libs/shared/src/*"]
}
}
}Environment Variables
Use .env files with Turborepo global dependencies:
{
"globalDependencies": ["**/.env.*"],
"globalEnv": ["DATABASE_URL", "JWT_SECRET", "NODE_ENV"]
}Monorepo package exports
For libs/shared:
{
"name": "shared",
"version": "0.0.0",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
}
}
}Next.js in Turborepo
Package Structure
apps/
web/
package.json
next.config.js
tsconfig.json
next-env.d.ts
libs/
ui/
package.json
tsconfig.json
index.tsweb/package.json
{
"name": "web",
"version": "0.0.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"next": "^15.1.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"ui": "*"
},
"devDependencies": {
"@next/eslint-plugin-next": "^15.1.0",
"typescript": "^5.7.2",
"eslint": "^9",
"eslint-config-next": "^15.1.0"
}
}turbo.json for Next.js
{
"$schema": "https://turborepo.dev/schema.json",
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "!.next/cache/**"],
"env": ["NEXT_PUBLIC_*"]
},
"dev": {
"cache": false,
"persistent": true
},
"lint": {
"outputs": []
}
}
}With app router
{
"pipeline": {
"build": {
"outputs": [
".next/**",
"!.next/cache/**",
".next/server/**"
]
}
}
}Incremental Static Regeneration (ISR)
For ISR with Next.js, exclude fetch cache from outputs:
{
"pipeline": {
"build": {
"outputs": [
".next/**",
"!.next/cache/**",
"!.next/server/pages/**/_buildManifest.js"
]
}
}
}Image optimization
Next.js image optimization cache should be excluded:
{
"pipeline": {
"build": {
"outputs": [
".next/**",
"!.next/cache/**",
"!.next/static/media/**"
]
}
}
}Package Configurations in Turborepo
Le Package Configurations permettono di definire comportamenti specifici per singoli package senza influenzare l'intero repository.
Struttura
apps/
web/
package.json
turbo.json # Package configuration
libs/
ui/
package.json
turbo.json # Package configuration
turbo.json # Root configurationEstendere dalla configurazione root
Ogni turbo.json in un package deve estendere dalla root:
{
"$schema": "https://turborepo.dev/schema.json",
"extends": ["//"],
"tasks": {
"build": {
"outputs": ["$TURBO_EXTENDS$", ".next/**"]
}
}
}Esempi di Package Configurations
Next.js con output specifici
apps/web/turbo.json:
{
"extends": ["//"],
"tasks": {
"build": {
"outputs": ["$TURBO_EXTENDS$", ".next/**", "!.next/cache/**"]
},
"dev": {
"dependsOn": ["^dev"]
}
}
}NestJS API
apps/api/turbo.json:
{
"extends": ["//"],
"tasks": {
"build": {
"outputs": ["$TURBO_EXTENDS$", "dist/**"]
},
"start:dev": {
"cache": false,
"persistent": true
}
}
}Libreria UI
libs/ui/turbo.json:
{
"extends": ["//"],
"tasks": {
"build": {
"outputs": ["$TURBO_EXTENDS$", "dist/**"]
},
"lint": {
"outputs": [],
"inputs": ["$TURBO_DEFAULT$", "src/**/*.tsx", "src/**/*.ts"]
},
"storybook": {
"cache": false,
"persistent": true
}
}
}Escludere task dall'ereditarietà
Usa extends: false per escludere un task:
{
"extends": ["//"],
"tasks": {
"lint": {
"extends": false
}
}
}O definisci un nuovo task non ereditato:
{
"extends": ["//"],
"tasks": {
"lint": {
"extends": false,
"outputs": [],
"inputs": ["src/**/*.ts"]
}
}
}Condividere configurazioni
Crea un package di configurazione condivisa:
packages/
turbo-config/
package.json
turbo.json
apps/
web/
turbo.jsonpackages/turbo-config/turbo.json:
{
"tasks": {
"build": {
"outputs": ["dist/**"]
},
"lint": {
"outputs": []
}
}
}apps/web/turbo.json:
{
"extends": ["//", "turbo-config"],
"tasks": {
"build": {
"outputs": ["$TURBO_EXTENDS$", ".next/**"]
}
}
}Variabili di Environment per Package
Definisci variabili specifiche per package:
{
"extends": ["//"],
"tasks": {
"build": {
"env": ["$TURBO_EXTENDS$", "NEXT_PUBLIC_STRIPE_KEY"]
}
}
}Task specifici per package
Definisci task che esistono solo in certi package:
{
"extends": ["//"],
"tasks": {
"storybook": {
"cache": false,
"persistent": true,
"description": "Run Storybook for UI components"
},
"chromatic": {
"dependsOn": ["build"],
"outputs": [],
"description": "Publish to Chromatic"
}
}
}Dipendenze specifiche per package
Definisci dipendenze tra task di package specifici:
{
"extends": ["//"],
"tasks": {
"build": {
"dependsOn": ["utils#build", "shared#build"]
}
}
}Sovrascrivere outputs
Sostituisci completamente gli outputs ereditati:
{
"extends": ["//"],
"tasks": {
"build": {
"outputs": [".next/**"] // Sostituisce, non aggiunge
}
}
}Oppure aggiungi agli outputs esistenti:
{
"extends": ["//"],
"tasks": {
"build": {
"outputs": ["$TURBO_EXTENDS$", ".next/**"]
}
}
}Best Practices
1. Estendi sempre dalla root con ["//"] 2. Usa `$TURBO_EXTENDS$` per aggiungere ai valori ereditati 3. Mantieni le configurazioni semplici - metti solo le differenze 4. Documenta i task custom con description 5. Evita duplicazioni - usa package config condivisi per pattern comuni 6. Testa localmente prima di committare configurazioni complesse
Testing in Turborepo
Vitest Configuration
Installation
pnpm add -D -w vitest @vitest/ui
pnpm add -D vitestvitest.config.ts
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
globals: true,
environment: 'node',
coverage: {
provider: 'v8',
reporter: ['text', 'json', 'html'],
exclude: [
'node_modules/',
'dist/',
'**/*.config.ts',
'**/*.d.ts'
]
}
}
})package.json scripts
{
"scripts": {
"test": "vitest run",
"test:watch": "vitest",
"test:ui": "vitest --ui",
"test:coverage": "vitest run --coverage"
}
}turbo.json for Vitest
{
"pipeline": {
"test": {
"dependsOn": ["build"],
"outputs": ["coverage/**"],
"inputs": ["$TURBO_DEFAULT$", "vitest.config.ts"],
"outputs": []
},
"test:watch": {
"cache": false,
"persistent": true
}
}
}Jest Configuration
Installation
pnpm add -D -w jest @types/jest
pnpm add -D jest ts-jest @types/jestjest.config.js
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
roots: ['<rootDir>/src'],
testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
transform: {
'^.+\\.ts$': 'ts-jest'
},
collectCoverageFrom: [
'src/**/*.ts',
'!src/**/*.d.ts',
'!src/**/*.interface.ts',
'!src/main.ts'
],
coverageDirectory: 'coverage',
coverageReporters: ['text', 'lcov', 'html']
}turbo.json for Jest
{
"pipeline": {
"test": {
"dependsOn": ["build"],
"outputs": ["coverage/**"],
"inputs": ["$TURBO_DEFAULT$", "jest.config.js"]
},
"test:watch": {
"cache": false,
"persistent": true
}
}
}Playwright Configuration
Installation
pnpm add -D -w @playwright/testplaywright.config.ts
import { defineConfig, devices } from '@playwright/test'
export default defineConfig({
testDir: './e2e',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: 'html',
use: {
baseURL: 'http://localhost:3000',
trace: 'on-first-retry'
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] }
}
],
webServer: {
command: 'pnpm run dev',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI
}
})turbo.json for Playwright
{
"pipeline": {
"test:e2e": {
"dependsOn": ["build"],
"outputs": ["playwright-report/**"],
"inputs": ["$TURBO_DEFAULT$", "playwright.config.ts"]
}
}
}Testing Strategies
Unit Tests (fast, isolated)
{
"pipeline": {
"test:unit": {
"outputs": [],
"inputs": ["src/**/*.ts", "test/unit/**/*.ts"]
}
}
}Integration Tests (slower, dependencies)
{
"pipeline": {
"test:integration": {
"dependsOn": ["build"],
"outputs": ["coverage/**"]
}
}
}E2E Tests (slowest, full system)
{
"pipeline": {
"test:e2e": {
"dependsOn": ["^build"],
"outputs": ["playwright-report/**"]
}
}
}Running Tests by Type
# Run all tests
turbo run test
# Run only unit tests
turbo run test:unit
# Run tests for affected packages
turbo run test --filter=[HEAD^]
# Run tests with coverage
turbo run test:coverageCI/CD Testing
# .github/workflows/ci.yml
- name: Run tests
run: pnpm run test --filter=[HEAD^]
- name: Run E2E tests
run: pnpm run test:e2e --filter=[HEAD^]Test Monorepo Patterns
Testing library changes
When a library changes, only test packages that depend on it:
turbo run test --filter=[HEAD^]Testing only changed packages
turbo run test --filter=...[HEAD]Parallel test execution
Turborepo automatically runs tests in parallel based on dependencies:
{
"pipeline": {
"test": {
"dependsOn": ["build"]
}
}
}{
"$schema": "https://turborepo.dev/schema.json",
"globalDependencies": ["**/.env.*local", ".env"],
"globalEnv": ["NODE_ENV", "CI"],
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**", "!.next/cache/**", "dist/**", "build/**"],
"env": ["NEXT_PUBLIC_*", "VITE_*", "NUXT_PUBLIC_*"]
},
"dev": {
"cache": false,
"persistent": true
},
"lint": {
"outputs": [],
"inputs": ["$TURBO_DEFAULT$", "!**/*.md", "!**/*.spec.ts", "!**/*.test.ts"]
},
"test": {
"dependsOn": ["build"],
"outputs": ["coverage/**"],
"inputs": ["$TURBO_DEFAULT$", "jest.config.js", "vitest.config.ts"]
},
"typecheck": {
"dependsOn": ["^build"],
"outputs": [],
"inputs": ["$TURBO_DEFAULT$", "tsconfig.json"]
},
"clean": {
"cache": false
}
}
}
Related skills
Forks & variants (1)
Turborepo Monorepo has 1 known copy in the catalog totaling 22 installs. They canonicalize to this original listing.
- giuseppe-trisciuoglio - 22 installs
How it compares
Pick turborepo-monorepo for Turborepo-specific GitHub Actions; pick generic pnpm CI skills when the repo is not using turbo.json task orchestration.
FAQ
Create workspace?
pnpm create turbo@latest then root turbo.json.
Test runners?
Vitest and Jest pipelines in monorepo.
Remote cache?
Vercel Remote Cache for CI and local.
Is Turborepo Monorepo safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.