Skip to content
📚 4 min read

Migrating from npm to pnpm ​

This guide covers the process of migrating your project from npm to pnpm, including command mappings, configuration changes, and best practices.

Prerequisites ​

  1. Install pnpm:
bash
# Using npm
npm install -g pnpm

# Using curl (Unix)
curl -fsSL https://get.pnpm.io/install.sh | sh -

# Using PowerShell (Windows)
iwr https://get.pnpm.io/install.ps1 -useb | iex
  1. Verify installation:
bash
pnpm --version

Migration Steps ​

1. Generate pnpm-lock.yaml ​

bash
# Remove npm's lock file
rm package-lock.json

# Generate pnpm-lock.yaml
pnpm install

2. Update CI Configuration ​

GitHub Actions ​

yaml
# Before (npm)
steps:
  - uses: actions/setup-node@v3
    with:
      node-version: '18'
  - run: npm ci
  - run: npm test

# After (pnpm)
steps:
  - uses: actions/setup-node@v3
    with:
      node-version: '18'
  - uses: pnpm/action-setup@v2
    with:
      version: 8
  - run: pnpm install --frozen-lockfile
  - run: pnpm test

3. Update Scripts ​

package.json ​

json
{
  "scripts": {
    // Before (npm)
    "start": "npm run build && node dist/index.js",
    "dev": "npm run build -- --watch",

    // After (pnpm)
    "start": "pnpm run build && node dist/index.js",
    "dev": "pnpm run build --watch"
  }
}

Command Mapping ​

Basic Commands ​

npmpnpm
npm installpnpm install
npm install [package]pnpm add [package]
npm install --save-dev [package]pnpm add -D [package]
npm uninstall [package]pnpm remove [package]
npm run [script]pnpm [script]
npm testpnpm test
npm run buildpnpm build

Advanced Commands ​

npmpnpm
npm cipnpm install --frozen-lockfile
npm auditpnpm audit
npm outdatedpnpm outdated
npm versionpnpm version
npm publishpnpm publish

Configuration Changes ​

1. Package Manager Settings ​

json
// package.json
{
  "packageManager": "pnpm@8.0.0"
}

2. pnpm Configuration ​

ini
# .npmrc
strict-peer-dependencies=true
auto-install-peers=true
shamefully-hoist=true

registry=https://registry.npmjs.org/

3. Git Configuration ​

gitignore
# .gitignore
node_modules
.pnpm-store/
.pnpm-debug.log

Workspace Migration ​

1. Update Workspace Configuration ​

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

2. Update Workspace Commands ​

bash
# Before (npm)
npm install --workspace=package-name
npm run test --workspaces

# After (pnpm)
pnpm --filter package-name install
pnpm -r run test

Store & Linking ​

Understanding pnpm's Store ​

bash
# Global store location
~/.pnpm-store/

# Project store
node_modules/.pnpm/
  • Each version of a package is saved once on disk
  • Multiple projects share the same package versions
  • Significant disk space savings

Best Practices ​

1. Store Management ​

  • Regular store maintenance
  • Use store path for CI caching
  • Verify store integrity
  • Clean unused packages

2. Dependency Management ​

  • Use strict peer dependencies
  • Regular dependency updates
  • Check for hoisting issues
  • Use overrides when needed

3. Performance ​

  • Enable hoisting when needed
  • Use parallel commands
  • Leverage workspace features
  • Maintain clean store

4. Security ​

  • Regular security audits
  • Use trusted sources
  • Review dependency changes
  • Keep pnpm updated

Common Issues ​

1. Hoisting Problems ​

ini
# .npmrc
shamefully-hoist=true
node-linker=hoisted

2. Peer Dependencies ​

bash
# Handle peer dependencies
pnpm install --no-strict-peer-dependencies

3. Store Issues ​

bash
# Verify store
pnpm store verify

# Clean store
pnpm store prune

Rollback Plan ​

If migration issues occur:

bash
# 1. Remove pnpm files
rm pnpm-lock.yaml
rm -rf node_modules
rm -rf .pnpm-store

# 2. Restore npm
npm install

# 3. Verify package-lock.json
git checkout package-lock.json
npm ci

Verification Steps ​

bash
# 1. Clean install
rm -rf node_modules
pnpm install

# 2. Run tests
pnpm test

# 3. Build project
pnpm build

# 4. Check dependencies
pnpm list

# 5. Check for issues
pnpm audit

Advanced Features ​

Filtering in Monorepos ​

bash
# Run in packages that depend on another
pnpm --filter ...package-name command

# Run in packages updated since main
pnpm --filter "[main]" command

# Run in specific packages
pnpm --filter "package-a...package-b" command

Custom Configs ​

js
// .pnpmfile.cjs
module.exports = {
  hooks: {
    readPackage(pkg) {
      // Modify package here
      return pkg;
    },
  },
};

Publishing ​

bash
# Publish package
pnpm publish

# Publish with custom tag
pnpm publish --tag beta

# Publish workspace packages
pnpm -r publish