0Pricing
Frontend Academy · Lesson

pnpm Workspaces for Monorepos

Set up a pnpm workspace with a root pnpm-workspace.yaml, hoist shared dependencies, and use workspace: protocol to link local packages.

pnpm Workspaces for Monorepos is a free Frontend Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Frontend Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Why pnpm?

pnpm (Performant npm) is a fast, disk-efficient package manager. It stores a single copy of each package in a global content-addressable store and links to it from project node_modules. Same dependency, multiple projects = one disk copy.

Speed and Disk Savings

On a typical monorepo, pnpm installs are 2-3x faster than npm/yarn and use ~70% less disk. Massive wins for monorepos with many packages.

Installing pnpm

Use Corepack (bundled with Node 16+) or install globally.

# Corepack (recommended):
corepack enable
corepack prepare pnpm@latest --activate

# Or:
npm install -g pnpm

Workspace Setup

Create a pnpm-workspace.yaml at the root listing folders containing packages.

# pnpm-workspace.yaml
packages:
  - 'apps/*'
  - 'packages/*'
  - '!**/test/**'

Project Structure

Each app and package has its own package.json. The root has a workspace package.json with shared devDeps.

my-monorepo/
  pnpm-workspace.yaml
  package.json         (root, private: true)
  apps/
    web/
      package.json
    docs/
      package.json
  packages/
    ui/
      package.json
    config-eslint/
      package.json

Installing Dependencies

Run pnpm install at the root once. pnpm installs everything in all packages, hoisting common deps.

pnpm install

# Install only in one workspace:
pnpm --filter web add react-router-dom

# Install dev dep at root:
pnpm add -Dw typescript prettier

workspace: Protocol

Reference internal packages with workspace:*. pnpm resolves to the local package; publish replaces it with a real version.

// apps/web/package.json
{
  "dependencies": {
    "@repo/ui": "workspace:*",
    "@repo/utils": "workspace:^1.0.0"
  }
}

// On publish, workspace:* becomes the actual version of @repo/ui.

Running Scripts Across Packages

pnpm -r runs a script in every package. Use --filter for subsets.

# Run build in every package:
pnpm -r build

# Only in web and its deps:
pnpm --filter web... build

# Run lint in changed packages since main:
pnpm --filter ...[origin/main] lint

Strict Dependency Resolution

By default, pnpm uses symlinks so a package only sees deps it explicitly listed in its package.json. No accidental cross-package leakage — a bug npm and yarn classic both allow.

hoist Patterns

By default pnpm hoists nothing. If a transitive dep needs to be accessible (e.g. a global TypeScript), add to .npmrc: shamefully-hoist=true (avoid if possible) or use specific public-hoist-pattern.

Updating Dependencies

pnpm update updates within semver ranges. pnpm update -L bumps to latest (ignoring caret).

pnpm update                      # update all
pnpm --filter web update react   # only react, only web
pnpm update -L                   # latest (ignore caret)

Combining with Turborepo

pnpm provides workspace + install; Turborepo provides task orchestration + caching. They pair perfectly — most JS monorepos use both.

# pnpm install dependencies
pnpm install

# Turborepo runs the tasks across the workspace:
pnpm turbo run build --filter=web...

CI Tips

Cache pnpm's content-addressed store (~/.local/share/pnpm/store) for faster CI. Use --frozen-lockfile to fail if pnpm-lock.yaml would change.

# .github/workflows/ci.yml
- uses: pnpm/action-setup@v3
  with: { version: 9 }
- uses: actions/setup-node@v4
  with: { node-version: '20', cache: 'pnpm' }
- run: pnpm install --frozen-lockfile
- run: pnpm -r build

Quick Check

What's the main disk-space advantage of pnpm over npm/yarn in a monorepo?

Recap: pnpm Workspaces

Single content-addressed store + symlinks = fast installs, ~70% less disk. pnpm-workspace.yaml lists packages folders. workspace:* protocol for internal deps. pnpm -r runs scripts across all packages; --filter for subsets. Strict resolution prevents leaky deps. Pair with Turborepo for task orchestration. Use --frozen-lockfile in CI.

Frequently asked questions

Is the “pnpm Workspaces for Monorepos” lesson free?

Yes — the full text of “pnpm Workspaces for Monorepos” is free to read here on the web, and the Frontend Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Frontend Academy course, upgrade to CoddyKit PRO.

What will I learn in “pnpm Workspaces for Monorepos”?

Set up a pnpm workspace with a root pnpm-workspace.yaml, hoist shared dependencies, and use workspace: protocol to link local packages. You practise Frontend Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Frontend Academy?

No prior experience is required. Frontend Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “pnpm Workspaces for Monorepos” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Frontend Academy lesson?

Yes. Every Frontend Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Vite: Plugin System and SSR Mode
  2. esbuild: Speed and Limitations
  3. pnpm Workspaces for Monorepos
  4. Turbo: Caching and Task Pipelines
← Back to Frontend Academy