pnpm 9 Workspaces: The Best Monorepo Package Manager in 2026
pnpm 9 introduces Catalogs for shared dependency versions and strict symlink node_modules that prevent phantom dependencies - here is the complete workspaces setup guide.
Mahmudul Haque Qudrati
CEO & ML Engineer
One AI engineering post, weekly
LLM benchmarks, prompt techniques, and token-cost breakdowns — not another AI news roundup.
Three reasons pnpm wins for monorepos in 2026:
- Content-addressable store - each version of a package is stored once globally, referenced by symlink. A monorepo with 10 apps sharing React doesn't store 10 copies of React.
- Strict node_modules - packages can only import what is in their own
package.json. Phantom dependencies (importing a package that happens to be installed by a sibling) cause runtime errors rather than silently working. - Catalogs - new in v9, define shared dependency versions at the workspace root to keep all packages in sync.
Workspace Setup
# pnpm-workspace.yaml (root)
packages:
- "apps/*"
- "packages/*"
// package.json (root)
{
"name": "my-monorepo",
"private": true,
"engines": { "node": ">=20.9.0", "pnpm": ">=9" }
}
Team workspace
Ship faster with chat, meetings, and projects in one place — Zlyqor.
Catalogs - pnpm v9 Feature
Catalogs define shared dependency versions in one place. No more version drift across packages:
# pnpm-workspace.yaml
packages:
- "apps/*"
- "packages/*"
catalog:
react: "^19.0.0"
react-dom: "^19.0.0"
typescript: "^5.5.0"
zod: "^3.23.0"
// apps/web/package.json
{
"dependencies": {
"react": "catalog:",
"react-dom": "catalog:"
},
"devDependencies": {
"typescript": "catalog:"
}
}
Update all packages at once: change the version in pnpm-workspace.yaml and run pnpm install.
Common Workspace Commands
# Install all workspace dependencies
pnpm install
# Add a dependency to a specific package
pnpm --filter web add react-query
# Add a shared devDependency to the root
pnpm add -D -w typescript
# Run build in all packages
pnpm -r run build
# Run build in all packages in dependency order
pnpm -r --workspace-concurrency=4 run build
# Run only in packages with changes (combine with Turborepo)
pnpm --filter "...[origin/main]" run build
# Run in a specific package
pnpm --filter web run dev
pnpm patch for Patching Dependencies
When a package has a bug and no fix is released yet:
# Create a patch
pnpm patch some-package@1.2.3
# Edit the files in the temp directory it creates
# Then apply the patch
pnpm patch-commit /path/to/temp-dir
This creates a .patches/some-package@1.2.3.patch file and adds it to pnpm-workspace.yaml:
patchedDependencies:
some-package@1.2.3: patches/some-package@1.2.3.patch
Production Docker With pnpm deploy
pnpm deploy creates a standalone deployment directory with only the production dependencies for one package:
FROM node:22-alpine AS base
RUN npm install -g pnpm@9
FROM base AS builder
WORKDIR /app
COPY . .
RUN pnpm install --frozen-lockfile
RUN pnpm --filter web build
FROM base AS runner
WORKDIR /app
# Deploy only web's production deps - no dev deps, no other packages
COPY --from=builder /app .
RUN pnpm deploy --filter=web --prod /deploy/web
FROM node:22-alpine AS final
WORKDIR /app
COPY --from=runner /deploy/web .
COPY --from=builder /app/apps/web/.next .next
CMD ["node", "server.js"]
Strict vs Hoisted Mode
pnpm's default (strict) prevents packages from accessing unlisted dependencies. If you have legacy code that relies on hoisted deps:
# .npmrc
hoist=false # default - strict (recommended)
# hoist=true # legacy - matches npm/yarn behavior
shamefully-hoist=false
Keep hoist=false in new projects. Fix the phantom dependency errors - they are real bugs waiting to happen in production.
References: pnpm · workspace docs · v9 changelog

Mahmudul Haque Qudrati
CEO & ML Engineer
Visionary technologist, software engineer, and machine learning specialist. Founder and CEO of Pristren, directing engineering teams that ship production-grade AI/ML pipelines, mission-critical full-stack applications, and developer tooling. Creator of Zlyqor, the unified team workspace platform. Author of 540+ technical guides and benchmark research reports on large language models, agentic workflows, Model Context Protocol (MCP), and modern web stacks.
More from Mahmudul
Related Articles
How to Use Claude to Make Videos Like Vox and Others
Claude can help you make Vox-style videos by generating scripts, editing with code, and automating animation. Here's a practical guide with real workflows and costs.
OpenAI Ends Cursor Model Access on Nov 12, 2026: What Developers Need to Know
OpenAI will terminate Cursor's access to its models on November 12, 2026, following SpaceX's acquisition. This guide explains the timeline, why it happened, and practical steps to migrate your workflow.
I Used Claude Code to Get a Second Opinion on My MRI: A Practical Overview
A developer fed his MRI scan to Claude Code and got a second opinion. Here's how the experiment worked, what it cost, and why you shouldn't rely on it for medical decisions.
// discussion
Comments