Skip to Content
DocsNode.jsMigrate from npm to pnpm

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'
Last updated on