| name | pnpm |
| description | pnpm package manager for fast, disk-efficient dependency management and workspaces. Use when user mentions "pnpm", "pnpm install", "pnpm workspace", "pnpm-workspace.yaml", "pnpm add", "pnpm store", "pnpm dlx", "content-addressable store", or managing Node.js packages with pnpm. |
pnpm
Fast, disk-efficient package manager for Node.js.
Installation
corepack enable
corepack prepare pnpm@latest --activate
curl -fsSL https://get.pnpm.io/install.sh | sh -
npm install -g pnpm
brew install pnpm
Why pnpm
Content-addressable store -- pnpm stores every package version exactly once in a global store. Projects hard-link to the store, so the same dependency across ten projects uses disk space only once.
Strict node_modules -- pnpm creates a non-flat node_modules. Packages can only access dependencies they explicitly declare. This prevents phantom dependencies that work by accident through hoisting.
Speed -- hard linking avoids redundant downloads and copies. Parallel resolution makes installs consistently faster than npm.
Basic Commands
pnpm install
pnpm add lodash
pnpm add -D typescript
pnpm add -g vercel
pnpm add lodash@4.17.21
pnpm remove lodash
pnpm update
pnpm update --latest
pnpm dlx create-next-app@latest
pnpm vs npm vs yarn
| Action | pnpm | npm | yarn |
|---|
| Install all | pnpm install | npm install | yarn |
| Add dependency | pnpm add pkg | npm install pkg | yarn add pkg |
| Add dev dep | pnpm add -D pkg | npm install -D pkg | yarn add -D pkg |
| Remove | pnpm remove pkg | npm uninstall pkg | yarn remove pkg |
| Run script | pnpm run dev | npm run dev | yarn dev |
| Execute binary | pnpm dlx pkg | npx pkg | yarn dlx pkg |
| Update | pnpm update | npm update | yarn up |
| Audit | pnpm audit | npm audit | yarn audit |
| Why installed | pnpm why pkg | npm why pkg | yarn why pkg |
Workspaces
pnpm-workspace.yaml
packages:
- 'packages/*'
- 'apps/*'
Filtering
pnpm --filter web run build
pnpm --filter "./apps/*" run build
pnpm --filter web... run build
pnpm --filter ...web run build
pnpm -r run build
pnpm -r --parallel run build
Workspace protocol
Reference sibling packages with workspace: in package.json:
{
"dependencies": {
"@myorg/shared": "workspace:*",
"@myorg/utils": "workspace:^1.0.0"
}
}
On publish, pnpm replaces workspace:* with the actual version. workspace:^ and workspace:~ produce the corresponding semver range.
Monorepo Patterns
Shared dependencies
Place shared dev dependencies in the workspace root. Use -w to add them:
pnpm add -Dw typescript eslint prettier
Peer dependencies
auto-install-peers=true
strict-peer-dependencies=false
.npmrc Configuration
shamefully-hoist=true
auto-install-peers=true
strict-peer-dependencies=false
enable-pre-post-scripts=true
use-node-version=20.11.0
registry=https://registry.npmjs.org/
@myorg:registry=https://npm.pkg.github.com
public-hoist-pattern[]=*eslint*
public-hoist-pattern[]=*prettier*
store-dir=/path/to/custom/store
Lock File
pnpm uses pnpm-lock.yaml. In monorepos it contains an importers section with per-package snapshots:
importers:
apps/web:
dependencies:
react:
specifier: ^18.2.0
version: 18.2.0
devDependencies:
typescript:
specifier: ^5.3.0
version: 5.3.3
Always commit pnpm-lock.yaml. Use --frozen-lockfile in CI.
Patching Dependencies
pnpm patch express@4.18.2
pnpm patch-commit /tmp/patch-dir-xxxxx
This adds a patchedDependencies entry to package.json:
{
"pnpm": {
"patchedDependencies": {
"express@4.18.2": "patches/express@4.18.2.patch"
}
}
}
Commit the patches/ directory.
Overrides
Force dependency versions across the entire tree:
{
"pnpm": {
"overrides": {
"lodash": "^4.17.21",
"got@<11.8.5": ">=11.8.5",
"express>debug": "~4.3.0"
}
}
}
Use overrides to fix transitive vulnerabilities or force version alignment.
Scripts
pnpm run dev
pnpm dev
pnpm --filter web run build
pnpm -r run test
pnpm -r --parallel run lint
pnpm does not run pre/post scripts by default. Enable with enable-pre-post-scripts=true in .npmrc.
Store Management
pnpm store path
pnpm store prune
pnpm store status
pnpm install --offline
Publishing from a Workspace
pnpm -r publish --access public
pnpm -r publish --dry-run
pnpm --filter "./packages/*" publish
pnpm replaces workspace: references with real version numbers during publish.
CI/CD
- uses: pnpm/action-setup@v4
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm -r run build
- run: pnpm -r run test
--frozen-lockfile fails if pnpm-lock.yaml is out of date, preventing accidental lockfile changes.
For generic CI, cache the directory from pnpm store path between builds.
Migration from npm/yarn
rm -rf node_modules package-lock.json
pnpm import
pnpm install
rm -rf node_modules yarn.lock
pnpm import
pnpm install
After migrating: replace npm ci / yarn --frozen-lockfile with pnpm install --frozen-lockfile in CI. Add pnpm-workspace.yaml if the project uses workspaces.