
3 Pitfalls I Hit Upgrading pnpm v10 to v11 — A Summary of Fixes for Docker and CI Environments
This page has been translated by machine translation. View original
Introduction
pnpm v11 was released, and I upgraded my project's package manager from v10. Things went relatively smoothly in my local environment, but my Docker builds and CI pipeline broke spectacularly.
In this article, I'll share the pitfalls I actually ran into and how I dealt with them, in a "here's what I tried" format. Honestly, pnpm v11 has quite a few breaking changes, and even after reading the official documentation, there were several traps that are easy to miss.
Prerequisites & Environment
- pnpm: v10.32.1 → v11 (latest)
- Node.js: 24 (LTS)
- Framework: Next.js 16
- Docker: node:24-slim base image
- CI: GitHub Actions
Major Breaking Changes in pnpm v11
Here's a summary of the key changes you should know before upgrading.
1. postinstall scripts are blocked by default
This was the biggest trap. Up through v10, postinstall scripts (such as building native modules) ran with a warning, but in v11, they result in an error unless explicitly permitted.
ERR_PNPM_IGNORED_BUILDS The following dependencies have build scripts that are not executed: sharp, unrs-resolver
2. The location of configuration files has changed
pnpm-specific settings written in .npmrc (such as hoist-pattern, node-linker, save-exact, etc.) are not read in v11. You need to migrate them to pnpm-workspace.yaml.
| Setting type | v10 | v11 |
|---|---|---|
| Registry & auth | .npmrc |
.npmrc (unchanged) |
| pnpm-specific settings | .npmrc |
pnpm-workspace.yaml |
package.json#pnpm |
Read | Ignored |
3. Environment variable prefix has changed
npm_config_* → pnpm_config_*. If you're using npm_config_* in your CI environment or Dockerfile, you'll need to update it.
4. Node.js 22 or higher is required
Support for Node.js 18–21 has been dropped.
3 Pitfalls I Actually Fell Into
Pitfall 1: Allowing postinstall scripts with allowBuilds
When running pnpm install, you'll get errors for packages that require native builds, such as sharp (image processing) and unrs-resolver (for ESLint).
Fix: Add allowBuilds to pnpm-workspace.yaml.
# frontend/pnpm-workspace.yaml
allowBuilds:
sharp: true
unrs-resolver: true
I also needed this at the project root for other packages:
# pnpm-workspace.yaml (root)
allowBuilds:
cpu-features: true
ssh2: true
Key point: You can tell which packages are affected by looking at the error message from pnpm install. Just add the package names shown in the error to allowBuilds and you're good.
onlyBuiltDependencies / neverBuiltDependencies / ignoredBuiltDependencies from v10 have been removed, so if you're already using any of these, you'll need to rewrite them using allowBuilds.
Pitfall 2: Forgetting to COPY pnpm-workspace.yaml in the Dockerfile
pnpm-workspace.yaml has become a required configuration file in v11. However, the existing Dockerfile only COPYed package.json and pnpm-lock.yaml.
Before (broken):
COPY frontend/package.json frontend/pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
After (working):
COPY frontend/package.json frontend/pnpm-lock.yaml frontend/pnpm-workspace.yaml ./
RUN pnpm install --frozen-lockfile
Without pnpm-workspace.yaml, the allowBuilds settings won't be loaded, postinstall scripts will be blocked, and your Docker build will fail.
Pitfall 3: ENV CI=true is required inside Docker
Even after fixing the two issues above, pnpm install inside Docker was still failing in some cases.
The cause was that when pnpm v11 detects an unpermitted postinstall script, it interactively prompts you to decide whether to allow it. Since there's no TTY during a Docker build, this prompt either hangs or causes an error.
Fix: Setting ENV CI=true puts pnpm into non-interactive mode, where it follows the allowBuilds configuration without showing any prompts.
FROM node:24-slim
ENV CI=true
RUN corepack enable && corepack prepare pnpm@latest --activate
WORKDIR /app
COPY frontend/package.json frontend/pnpm-lock.yaml frontend/pnpm-workspace.yaml ./
RUN pnpm install --frozen-lockfile
It's just one line — ENV CI=true — but without it, the Docker build silently stalls, which made it very time-consuming to identify the cause.
CI (GitHub Actions) Fixes
In GitHub Actions, I also needed to update the version specified in pnpm/action-setup.
# Before
- uses: pnpm/action-setup@v4
with:
version: 10
# After
- uses: pnpm/action-setup@v4
with:
version: latest
Since CI=true is set by default in the GitHub Actions environment, no additional workaround was needed like in Docker. However, if pnpm-workspace.yaml isn't properly committed to the repository, you'll see the same ERR_PNPM_IGNORED_BUILDS error in CI as well.
Honest Thoughts
Upgrading to pnpm v11 was, frankly, a pain.
The good:
- Explicitly requiring permission for postinstall scripts via
allowBuildsis the right direction from a security standpoint, as a defense against supply chain attacks - Making
minimumReleaseAge(which prevents resolving packages published less than 24 hours ago) enabled by default is also a good call - Having settings consolidated in
pnpm-workspace.yamlwill be easier to understand in the long run
The painful:
- The "warning → error" change is the most impactful breaking change for users, and you often don't notice it until it blows up in a non-interactive environment like CI or Docker
- The need to COPY
pnpm-workspace.yamlin the Dockerfile should have been highlighted more prominently in the official Docker guide - The requirement for
ENV CI=trueis not documented anywhere; I only discovered it through trial and error - There are so many breaking changes that it's hard to grasp them all at once even after reading the official migration guide
All in all, pnpm v11 represents a major shift toward a security-first design philosophy. The default-deny approach for allowBuilds, minimumReleaseAge, blockExoticSubdeps — all of these changes err on the side of caution. I think the direction is right, but the migration cost is non-trivial.
Upgrade Steps Summary
- Run
pnpx codemod run pnpm-v10-to-v11to handle mechanical configuration migration - Run
pnpm installand check the package names appearing inERR_PNPM_IGNORED_BUILDSerrors - Add
allowBuildstopnpm-workspace.yaml - Add the COPY of
pnpm-workspace.yamlto your Dockerfile - Add
ENV CI=trueto your Dockerfile - Update the pnpm version in your CI configuration (GitHub Actions, etc.)
- Migrate pnpm-specific settings from
.npmrctopnpm-workspace.yaml - Regenerate the lockfile (auto-updated by running
pnpm install)