Best npm Workspaces Alternatives 2026
·PkgPulse Team
TL;DR
npm workspaces are the least capable option — pnpm workspaces are the 2026 default for monorepos. npm workspaces lack per-workspace filtering, have no dependency isolation (all packages see all deps via hoisting), and have slower install. pnpm workspaces + Turborepo or Moon is the dominant stack: pnpm handles package resolution + isolation, Turborepo/Moon handles task caching. Yarn Berry (PnP mode) is a third option for teams already on Yarn.
Key Takeaways
- pnpm workspaces: Best filtering (
--filter), strictest isolation,pnpm-workspace.yaml - Bun workspaces: Fastest install, basic filtering, JSON-only config
- npm workspaces: Universal but limited filtering, no isolation, slowest
- Yarn Berry (PnP): Zero node_modules, but PnP compatibility issues persist in 2026
- Combine with: Turborepo, Nx, or Moon for task caching/orchestration on top of any workspace
- Protocol:
workspace:*in pnpm/Yarn links local packages (better than symlinks)
pnpm Workspaces: The Standard
# pnpm-workspace.yaml (root):
packages:
- 'apps/*'
- 'packages/*'
- 'tools/*'
- '!**/node_modules/**'
// packages/ui/package.json — local dependency:
{
"name": "@myapp/ui",
"version": "1.0.0",
"main": "./dist/index.js",
"types": "./dist/index.d.ts"
}
// apps/web/package.json — consuming the local package:
{
"name": "web",
"dependencies": {
"@myapp/ui": "workspace:*", // pnpm workspace protocol
"react": "^19.0.0"
}
}
# pnpm workspace filtering — the killer feature:
# Run command in specific package:
pnpm --filter web run dev
pnpm --filter @myapp/ui run build
# Run in package and all its dependencies:
pnpm --filter web... run build
# Run in packages that depend on @myapp/ui:
pnpm --filter ...@myapp/ui run build
# Run in all packages matching glob:
pnpm --filter './packages/**' run test
# Add dep to specific workspace:
pnpm --filter web add axios
pnpm --filter @myapp/ui add -D vitest
# Run in all packages:
pnpm -r run build # Recursive
pnpm -r run test --if-present # Only if test script exists
pnpm Workspace Isolation
pnpm workspace isolation (default):
→ apps/web can only import packages in its own node_modules
→ Symlinks to packages/@myapp/ui (not copied)
→ Phantom dependencies are an error (not silently allowed)
→ Each package's node_modules contains ONLY what it declares
npm workspace (hoisted, no isolation):
→ All packages share root node_modules
→ apps/web can accidentally import packages/ui's deps
→ Phantom dependencies silently work (until they don't)
→ This is why "works on my machine" happens in npm monorepos
npm Workspaces: Universal Baseline
// package.json (root):
{
"name": "my-monorepo",
"workspaces": [
"apps/*",
"packages/*"
]
}
# npm workspace commands:
npm install # Install all workspaces
npm install --workspace=apps/web # Install specific workspace
npm run build --workspace=apps/web # Run in specific workspace
npm run build --workspaces # Run in all workspaces
npm run build --workspaces --if-present # Skip if no script
# No --filter or dependency graph traversal like pnpm
# No "build web and all its deps" command
npm Workspace Limitations
npm workspace gaps vs pnpm:
❌ No "build only affected packages" capability
❌ No graph-based filtering (build web + its deps)
❌ No strict isolation (phantom dependencies allowed)
❌ Slower install (~3x slower than pnpm)
❌ No workspace:* protocol (uses relative paths instead)
❌ workspace-root not always respected
npm workspaces → OK for small repos with 2-3 packages
npm workspaces → NOT OK for large monorepos with 10+ packages
Bun Workspaces: Speed-First
// package.json (root) — same format as npm:
{
"name": "my-monorepo",
"workspaces": [
"apps/*",
"packages/*"
]
}
# Bun workspace commands:
bun install # Install all (fast!)
bun add react --workspace apps/web # Add to specific workspace
bun run --filter '*' build # Run in all workspaces
bun run --filter 'apps/*' dev # Run in apps only
Bun workspace features vs pnpm:
✅ Much faster install (5-10x)
✅ Basic filtering (--filter glob)
❌ No graph-based filtering
❌ No workspace:* protocol (still experimental)
❌ Smaller ecosystem of compatibility
❌ Some packages don't install correctly with Bun
Yarn Berry (PnP): Zero node_modules
# Enable Yarn Berry in existing project:
yarn set version stable # Or: yarn set version berry
# .yarnrc.yml:
nodeLinker: pnp # Plug'n'Play (no node_modules)
# Or:
nodeLinker: node-modules # Traditional (more compatible)
# Yarn workspaces commands:
yarn workspace web add axios # Add to specific workspace
yarn workspaces foreach run build # Run in all workspaces
yarn workspaces foreach -p run build # Parallel across workspaces
Yarn Berry PnP status in 2026:
✅ Zero disk usage (no node_modules copies)
✅ Strict dependency isolation
✅ Fast install via zip cache
❌ PnP compatibility still has edge cases
❌ Some tools don't understand PnP resolution
❌ Requires editor configuration (Yarn SDK)
❌ Smaller community momentum vs pnpm
Verdict: Technically impressive, but pnpm better balance of
features/compatibility for most teams in 2026.
Workspace Tooling Comparison
| Feature | pnpm | Bun | npm | Yarn Berry |
|---|---|---|---|---|
| Install speed | Fast | Fastest | Slow | Fast |
| Disk usage | Low | Low | High | Lowest (PnP) |
| Isolation | ✅ Strict | Partial | ❌ None | ✅ Strict |
| Graph filtering | ✅ --filter | Partial | ❌ | ✅ |
| workspace: protocol | ✅ | ❌ | ❌ | ✅ |
| Compatibility | High | Medium | Highest | Medium |
| Turborepo support | ✅ | ✅ | ✅ | ✅ |
| Nx support | ✅ | ✅ | ✅ | ✅ |
Recommended Stack
For most JavaScript monorepos in 2026:
Package manager: pnpm workspaces
Task runner: Turborepo (v2, Rust-based) or Moon
CI caching: Vercel Remote Cache (Turborepo) or GitHub Actions cache
Setup:
1. pnpm-workspace.yaml with packages/apps globs
2. turbo.json with build/test/lint tasks
3. workspace:* protocol in all internal deps
4. pnpm --filter for workspace-specific commands
This combination:
→ 3-5x faster installs than npm
→ Up to 25x faster builds (Turborepo cache)
→ Strict deps (no phantom dependency bugs)
→ Best DX for monorepo development
Compare package manager downloads on PkgPulse.