Skip to main content

Migrate from NPM to PNPM

· 3 min read
Daniel Guo
Software Engineer

The benefits of pnpm over npm

Performance

  • Faster installs: pnpm uses a content-addressable store and hard links files from the global store to node_modules, which avoids redundant downloads and file copying.
  • Parallelization: It aggressively parallelizes operations more than npm, especially for network I/O and linking.

Disk Space Efficiency

  • Content-addressable store: Dependencies are stored in a single location on disk (~/.pnpm-store) and symlinked into projects. This avoids duplication across projects, saving significant disk space—especially in monorepos.
  • No duplication in monorepos: All packages and versions share the same cache, which avoids redundant installations.

Strict and Deterministic Installations

  • Strict node_modules layout: pnpm prevents packages from accessing undeclared dependencies by default (unlike npm, which flattens dependencies).
  • Better adherence to package.json: If a dependency is not declared, it’s not accessible. This encourages correct dependency declarations.
  • Reproducibility: pnpm-lock.yaml combined with pnpm’s structure leads to more deterministic builds compared to npm.

Isolation and Compatibility

  • Isolated node_modules: No pollution from global installs or peer dependencies leaking into unrelated packages.
  • Better handling of peerDependencies: pnpm forces you to satisfy peer dependencies correctly, helping avoid runtime errors.

CLI Features and Ecosystem

  • Commands like pnpm why, pnpm m ls, pnpm m run in monorepos are fast and powerful.
  • Good integration with CI workflows and modern JavaScript tooling.

When to Use pnpm

Use pnpm if:

  • You’re working in a monorepo.
  • You want to optimize CI performance.
  • You care about strict dependency boundaries.
  • You want to save disk space across projects.

Migration Steps

Here is my migration experience for a Node.js application.

Install pnpm:

# on Mac
❯ brew install pnpm

# with node.js installed
❯ npm install -g pnpm

Steps


# Remove existing dependencies and the NPM lock file
❯ rm -rf node_modules package-lock.json

# Optional: clear .npmrc and .npm cache if they contain custom registry settings
❯ rm -rf ~/.npmrc ~/.npm

# Install dependencies
❯ pnpm install

Update Scripts

  • npm run test => pnpm test
  • npm start => pnpm start
  • npx prisma migrate dev --name "$1" --schema=app/prisma/schema.prisma => pnpm dlx prisma migrate dev --name "$1" --schema=app/prisma/schema.prisma

Update Dockerfile

Install PNPM and migrate related commands:

RUN npm install -g pnpm@latest-10

RUN pnpm install

RUN pnpm dlx prisma generate --schema=app/prisma/schema.prisma

CMD ["pnpm", "start"]

Update CI/CD

  • Use pnpm/action-setup
  • Use cache to reduce installation time
on:
- push
- pull_request
jobs:
deploy:
name: Deploy to AWS ECS - ${{ inputs.environment }}
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ inputs.branch }}

- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 10
run_install: false

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "22.x"
cache: "pnpm"

References