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 at Pristren

Mahmudul Haque Qudrati

CEO & ML Engineer

April 27, 2026
7 min read
pnpm 9 Workspaces: The Best Monorepo Package Manager in 2026

Why pnpm Over npm or Yarn?

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:

  1. 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.
  2. 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.
  3. Catalogs - new in v9, define shared dependency versions at the workspace root to keep all packages in sync.

Workspace Setup

yaml
# pnpm-workspace.yaml (root)
packages:
  - "apps/*"
  - "packages/*"
json
// 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.

Start free

Catalogs - pnpm v9 Feature

Catalogs define shared dependency versions in one place. No more version drift across packages:

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

catalog:
  react: "^19.0.0"
  react-dom: "^19.0.0"
  typescript: "^5.5.0"
  zod: "^3.23.0"
json
// 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

bash
# 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:

bash
# 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:

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:

dockerfile
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:

ini
# .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

#pnpm#workspaces#monorepo#package-manager#symlinks

// discussion

Comments

0/4000
Mahmudul Haque Qudrati — CEO & ML Engineer at Pristren

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.

PristrenZlyqor