Using pnpm and pnpm workspaces

Just as an informative note for future users, here some info on how to workaround Netlify’s CI in order to use pnpm instead of npm or yarn and pnpm workspaces.

  1. Remove your package-lock.json or yarn.lock file and add it to your .gitignore, if applicable. Be sure to track pnpm-lock.yaml instead.

  2. If you’re using workspaces: add pnpm itself as a dev dependency on your top-level project, this so it is possible to use pnpm recursive commands inside your build scripts

    pnpm install --save-dev pnpm@3
  3. Add the NPM_FLAGS="--prefix=/" env var to your netlify.toml or set it on Netlify’s web dashboard


    This makes netlify skip their automatic npm install, to let pnpm take care of it.

  4. Add pnpm install as a build step in your build process, only for Netlify, most probably before anything else. Assuming your build command is npm run build , you might add the following script into your top-level package.json:

    "prebuild": "[[ $CI = true ]] && npx pnpm@3 install -r --store=node_modules/.pnpm-store || echo skiping pnpm install"

    Use the -r option only if you’re using workspaces. The --store option tells pnpm where to save its “global” cache. I initially tried to save it to the netlify cache dir, but netlify is picky on what saves in cache for the next build. Even when I was able to make netlify save the pnpm cache, the install was not very efficient because pnpm had to resort to the copy strategy because netlify mounts the cache folder in a different drive, so symlinking is not possible. Saving the store into node_modules makes the install quite fast.

We have been using this setup in prod without issues for a while now. And unlike with yarn, we haven’t experienced issues with missing node_modules inside workspaces, since pnpm stores every dep inside the top-level node_modules (which is the only Netlify saves for cache) and pnpm install simply creates symlinks.

1 Like

thank you for sharing this!! this is very useful for people!

1 Like