Files
agent-skills/skills/turborepo/references/best-practices/dependencies.md
Jason Woltje f5792c40be feat: Complete fleet — 94 skills across 10+ domains
Pulled ALL skills from 15 source repositories:
- anthropics/skills: 16 (docs, design, MCP, testing)
- obra/superpowers: 14 (TDD, debugging, agents, planning)
- coreyhaines31/marketingskills: 25 (marketing, CRO, SEO, growth)
- better-auth/skills: 5 (auth patterns)
- vercel-labs/agent-skills: 5 (React, design, Vercel)
- antfu/skills: 16 (Vue, Vite, Vitest, pnpm, Turborepo)
- Plus 13 individual skills from various repos

Mosaic Stack is not limited to coding — the Orchestrator and
subagents serve coding, business, design, marketing, writing,
logistics, analysis, and more.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:27:42 -06:00

4.2 KiB

Dependency Management

Best practices for managing dependencies in a Turborepo monorepo.

Core Principle: Install Where Used

Dependencies belong in the package that uses them, not the root.

# Good: Install in specific package
pnpm add react --filter=@repo/ui
pnpm add next --filter=web

# Avoid: Installing in root
pnpm add react -w  # Only for repo-level tools!

Benefits of Local Installation

1. Clarity

Each package's package.json lists exactly what it needs:

// packages/ui/package.json
{
  "dependencies": {
    "react": "^18.0.0",
    "class-variance-authority": "^0.7.0"
  }
}

2. Flexibility

Different packages can use different versions when needed:

// packages/legacy-ui/package.json
{ "dependencies": { "react": "^17.0.0" } }

// packages/ui/package.json
{ "dependencies": { "react": "^18.0.0" } }

3. Better Caching

Installing in root changes workspace lockfile, invalidating all caches.

4. Pruning Support

turbo prune can remove unused dependencies for Docker images.

What Belongs in Root

Only repository-level tools:

// Root package.json
{
  "devDependencies": {
    "turbo": "latest",
    "husky": "^8.0.0",
    "lint-staged": "^15.0.0"
  }
}

NOT application dependencies:

  • react, next, express
  • lodash, axios, zod
  • Testing libraries (unless truly repo-wide)

Installing Dependencies

Single Package

# pnpm
pnpm add lodash --filter=@repo/utils

# npm
npm install lodash --workspace=@repo/utils

# yarn
yarn workspace @repo/utils add lodash

# bun
cd packages/utils && bun add lodash

Multiple Packages

# pnpm
pnpm add jest --save-dev --filter=web --filter=@repo/ui

# npm
npm install jest --save-dev --workspace=web --workspace=@repo/ui

# yarn (v2+)
yarn workspaces foreach -R --from '{web,@repo/ui}' add jest --dev

Internal Packages

# pnpm
pnpm add @repo/ui --filter=web

# This updates package.json:
{
  "dependencies": {
    "@repo/ui": "workspace:*"
  }
}

Keeping Versions in Sync

Option 1: Tooling

# syncpack - Check and fix version mismatches
npx syncpack list-mismatches
npx syncpack fix-mismatches

# manypkg - Similar functionality
npx @manypkg/cli check
npx @manypkg/cli fix

# sherif - Rust-based, very fast
npx sherif

Option 2: Package Manager Commands

# pnpm - Update everywhere
pnpm up --recursive typescript@latest

# npm - Update in all workspaces
npm install typescript@latest --workspaces

Option 3: pnpm Catalogs (pnpm 9.5+)

# pnpm-workspace.yaml
packages:
  - "apps/*"
  - "packages/*"

catalog:
  react: ^18.2.0
  typescript: ^5.3.0
// Any package.json
{
  "dependencies": {
    "react": "catalog:"  // Uses version from catalog
  }
}

Internal vs External Dependencies

Internal (Workspace)

// pnpm/bun
{ "@repo/ui": "workspace:*" }

// npm/yarn
{ "@repo/ui": "*" }

Turborepo understands these relationships and orders builds accordingly.

External (npm Registry)

{ "lodash": "^4.17.21" }

Standard semver versioning from npm.

Peer Dependencies

For library packages that expect the consumer to provide dependencies:

// packages/ui/package.json
{
  "peerDependencies": {
    "react": "^18.0.0",
    "react-dom": "^18.0.0"
  },
  "devDependencies": {
    "react": "^18.0.0",      // For development/testing
    "react-dom": "^18.0.0"
  }
}

Common Issues

"Module not found"

  1. Check the dependency is installed in the right package
  2. Run pnpm install / npm install to update lockfile
  3. Check exports are defined in the package

Version Conflicts

Packages can use different versions - this is a feature, not a bug. But if you need consistency:

  1. Use tooling (syncpack, manypkg)
  2. Use pnpm catalogs
  3. Create a lint rule

Hoisting Issues

Some tools expect dependencies in specific locations. Use package manager config:

# .npmrc (pnpm)
public-hoist-pattern[]=*eslint*
public-hoist-pattern[]=*prettier*

Lockfile

Required for:

  • Reproducible builds
  • Turborepo dependency analysis
  • Cache correctness
# Commit your lockfile!
git add pnpm-lock.yaml  # or package-lock.json, yarn.lock