pnpmnpmfrontendnode.jstoolchain

pnpm in Practice: Installation, Migration, and Workspaces

pnpm is ideal for developers maintaining multiple frontend projects. It reuses dependencies through a global content-addressable store, reducing node_modules footprint, speeding up installs, and catching phantom dependency issues with stricter resolution.

2026-06-25·9 min·计算中...
pnpm in Practice: Installation, Migration, and Workspaces

If you maintain several frontend projects at once, node_modules quickly becomes a black hole for disk space. A single React, Next.js, Vite, or mini-program project can easily start at several hundred megabytes — and when multiple projects install the same dependencies separately, the waste adds up fast.

That's where pnpm shines. Instead of storing a copy of each package in every project, it places packages in a global content-addressable store and links them into each project. The result: faster installs, lower disk usage, and stricter dependency resolution.

Why pnpm

Traditional npm or older yarn work more like "one copy per project":

project-a/node_modules/react   <- one copy
project-b/node_modules/react   <- another copy
project-c/node_modules/react   <- yet another copy

pnpm centralizes packages in a global store:

~/.pnpm-store/react@18.x       <- one copy globally
project-a/node_modules         <- linked to store
project-b/node_modules         <- linked to store
project-c/node_modules         <- linked to store

For day-to-day development, this delivers three concrete benefits:

  • Saves disk space: multiple projects share the same dependency content — especially useful on a MacBook with many local projects.
  • Faster installs: packages already downloaded are reused directly from the local store.
  • More controlled dependencies: pnpm does not allow projects to access undeclared dependencies by default, surfacing phantom dependency issues earlier.

Installing pnpm on Mac

If you already use Homebrew, installing through it keeps your toolchain consistent:

brew install pnpm

Verify the installation:

pnpm --version

If you want to store pnpm's global cache on a specific drive — such as an external SSD — configure store-dir:

pnpm config set store-dir /Volumes/your-disk/pnpm-store

Most users don't need to change this. The default is perfectly fine. Only consider a custom path if your internal drive is tight on space or you want to centralize your dev caches.

npm vs pnpm Command Reference

Task npm pnpm
Install all dependencies npm install pnpm install
Add a production dependency npm install react pnpm add react
Add a dev dependency npm install -D eslint pnpm add -D eslint
Install a global tool npm install -g xxx pnpm add -g xxx
Remove a dependency npm uninstall xxx pnpm remove xxx
Run a script npm run dev pnpm dev
Execute a one-off tool npx create-next-app pnpm dlx create-next-app
View dependency tree npm ls pnpm list
Check for outdated packages npm outdated pnpm outdated
Upgrade dependencies npm update pnpm update
Clean store npm cache clean pnpm store prune

Most scripts can omit run:

pnpm dev
pnpm build
pnpm lint

Use the full form only when a script name conflicts with a pnpm built-in:

pnpm run test

Migrating an Existing Project to pnpm

Switching from npm or yarn is a three-step process.

Step 1 — remove the old dependency directory and lockfile:

rm -rf node_modules
rm -f package-lock.json yarn.lock

Step 2 — reinstall dependencies:

pnpm install

This generates a fresh pnpm-lock.yaml.

Step 3 — verify the project starts and builds correctly:

pnpm dev
pnpm build

For larger projects, avoid migrating directly on the main branch. A safer approach is to branch first:

git checkout -b feat/migrate-to-pnpm
rm -rf node_modules package-lock.json yarn.lock
pnpm install
pnpm dev
pnpm build

Once dev, build, test, and deployment all pass, merge the migration.

Which Projects to Migrate First

Not every project needs to switch immediately. Prioritize by risk and reward:

Project type Timing Reason
New projects Start with pnpm No legacy lockfiles or CI compatibility concerns
Active projects with many dependencies Migrate early Disk and install-time savings are most noticeable
Internal tools and admin panels Good candidate Usually controllable, low verification cost
Projects nearing a deadline Hold off Stability first — don't add variables close to release
SSR or complex 3D dependency stacks Test on a branch Validate builds, dynamic imports, and deploy environment carefully

Switching package managers isn't a product feature. If you're in a sprint, wait for the next iteration.

Common Issues and Fixes

Package not found

pnpm's node_modules is not a traditional flat structure. Well-maintained packages declare all their dependencies, but some older or poorly configured tools quietly rely on packages hoisted to the project root — the classic "phantom dependency" problem.

If you hit a compatibility issue, add .npmrc to your project root:

shamefully-hoist=true

This makes pnpm's hoisting behavior closer to npm, improving compatibility at the cost of some dependency isolation. Treat it as a fallback, not a default for all projects.

Mini-program toolchains can't find dependencies

WeChat mini-programs and similar platforms often have their own dependency build flows. After installing with pnpm, if dependencies aren't available in the developer tool, try reinstalling first:

pnpm install

Then run "Build npm" again inside the developer tool. If the toolchain has poor symlink support, consider shamefully-hoist=true or stick with npm for that project.

AI coding assistants defaulting to npm

If you use Claude Code, Codex, or other AI coding tools, document your package manager choice explicitly to prevent them from running npm install and generating a package-lock.json.

Add something like this to your README.md, CONTEXT.md, or project conventions doc:

## Development Conventions

- Package manager: pnpm
- Install dependencies: pnpm install
- Add a package: pnpm add <package>
- Do not run npm install or commit package-lock.json

Resolving pnpm-lock.yaml conflicts

In collaborative projects, pnpm-lock.yaml can also produce merge conflicts. Lockfiles aren't meant to be hand-edited in bulk. The safest approach is to pick one side's version and reinstall.

For example, keep your current branch's lockfile and re-resolve:

git checkout HEAD -- pnpm-lock.yaml
pnpm install

Or, if you're merging from the target branch, take that side and run pnpm install again. The goal is to let pnpm regenerate a consistent resolution — not to manually patch YAML.

Migration Checklist for Next.js Projects

Stacks combining Next.js, Three.js, GSAP, or Howler.js tend to be more sensitive around SSR, browser APIs, and build environments. Verify these specifically before merging:

git checkout -b feat/migrate-to-pnpm
rm -rf node_modules package-lock.json yarn.lock
pnpm install
pnpm list next react react-dom
pnpm dev
pnpm build

If your project includes browser-only libraries, keep the existing SSR-safe patterns — next/dynamic with ssr: false. Switching package managers doesn't fix SSR issues; it only changes how dependencies are installed and resolved.

Useful Advanced Commands

Find out why a package is installed:

pnpm why react

Install production dependencies only (common in deploy environments):

pnpm install --prod

Interactively upgrade dependencies:

pnpm update --interactive

Check store integrity:

pnpm store status

Remove store content no longer used by any project:

pnpm store prune

When to Use pnpm Workspaces

Once you start putting multiple frontend apps, component libraries, design tokens, and scripts into a single repository, pnpm workspace becomes valuable.

A typical structure looks like this:

project/
├── pnpm-workspace.yaml
├── apps/
│   ├── web/
│   └── admin/
└── packages/
    ├── ui/
    └── config/

Create pnpm-workspace.yaml at the root:

packages:
  - 'apps/*'
  - 'packages/*'

Workspaces are built for monorepos. Don't introduce them just because they sound sophisticated. If you have a single app today, plain pnpm is enough. Upgrade to a workspace when you genuinely need to share components, config, or tooling across multiple packages.

A Phased Approach

If you haven't used pnpm in a production project yet, here's a reasonable pace:

Now          -> Pick a lower-risk active project and migrate it
This week    -> Get comfortable with pnpm add, pnpm dev, pnpm why
Next sprint  -> Branch-test migration on a more critical project
Later        -> Consider pnpm workspace when you need cross-package sharing

One-line summary: pnpm is a great fit for multi-project developers, but don't stop at "install succeeded." The real validation is getting dev, build, test, and deployment all the way through.

Subscribe to FreeMac

Weekly picks: free Mac software reviews, trusted source updates, alternatives, and low-friction guides.