loke.dev
Configuration card moving from a project folder to a workspace settings file beside a dependency graph

pnpm 11 Ignored Your Overrides: Move Config Before CI Rewrites It

pnpm 11 moved project settings out of package.json. Migrate overrides and build policy to pnpm-workspace.yaml before CI rewrites your lockfile.

Published By Loke4 min read

A dependency override is often security configuration in disguise. You add one to keep a bad transitive version out of the lockfile, then assume the package manager will keep enforcing it. That assumption becomes dangerous during a major upgrade.

pnpm 11 changes where project settings live. If your repository still keeps pnpm configuration inside package.json, treat the upgrade as a configuration migration, not just a version bump. The failure mode can be subtle: install succeeds, the lockfile changes, and the setting you expected to protect the dependency graph is no longer applied.

The symptom: a clean install changes more than you expected

pnpm 11’s release notes say that project settings are no longer read from the pnpm field in package.json. The canonical project-level home is pnpm-workspace.yaml. The same release also moves most non-auth settings out of .npmrc, changes build-script controls, and requires Node.js 22 or newer.

An early pnpm 11 issue documented overrides and patchedDependencies being ignored when left in package.json, with the resulting lockfile omitting the expected override section. The report covers affected early 11.x releases, not every later version, so verify the exact pnpm version you run. But the migration itself is still the correct fix.

Find the configuration before you upgrade

Start with a repository search. You are looking for pnpm configuration in package.json, workspace-local .npmrc files, and CI environment variables using the old npm_config_ prefix. Do this before regenerating a lockfile so the diff remains an audit trail instead of a mystery.

rg -n '"pnpm"|overrides|patchedDependencies|onlyBuiltDependencies|ignoreDepScripts|npm_config_' \
  package.json pnpm-workspace.yaml .npmrc .github 2>/dev/null

Do not copy settings blindly. Some old build-dependency settings were removed and replaced by allowBuilds. Others are workspace-level settings that belong in pnpm-workspace.yaml. Check the v11 migration notes against the settings your repository actually uses.

Move the intent, not just the YAML

A common legacy setup keeps overrides in package.json. In pnpm 11, place the project configuration in the workspace file instead. The exact packages below are placeholders. Preserve your own constraint and review why each override exists before carrying it forward.

// package.json (legacy location)
{
  "pnpm": {
    "overrides": {
      "some-transitive-package@<2.4.0": ">=2.4.0"
    }
  }
}
# pnpm-workspace.yaml
packages:
  - '.'

overrides:
  some-transitive-package@<2.4.0: '>=2.4.0'

# Add migrated patchedDependencies and other project settings here too.

The pnpm workspace file is also the workspace root and, in v11, supports project-specific packageConfigs. That matters in monorepos: avoid recreating per-project .npmrc behavior by scattering new configuration files through packages.

Audit build scripts separately

pnpm 11 removes older build-dependency settings in favor of allowBuilds. This is not a cosmetic rename. Build scripts are part of your supply-chain policy, so write an explicit allow or deny decision for every package that needs one. Do not globally allow scripts just to make an install go green.

# pnpm-workspace.yaml
allowBuilds:
  esbuild: true
  sharp: true
  unwanted-package: false

Make the migration prove itself in CI

The useful check is not “did pnpm install finish?” It is “did the resolved graph and lockfile preserve the policy we intended?” Pin the package-manager version, install with the same command CI uses, and inspect the resulting diff. If an override is important, make its presence in the lockfile or resolved tree an intentional assertion.

# Run with the pnpm 11 version pinned by your repository/toolchain.
pnpm --version
pnpm install --frozen-lockfile
pnpm why some-transitive-package

git diff --exit-code -- pnpm-lock.yaml

Use a temporary upgrade branch for the first run. A frozen lockfile should fail if your configuration migration was incomplete, which is better than discovering the discrepancy after an automated dependency update has already rewritten the lockfile.

A short upgrade checklist

1. Pin pnpm 11 and confirm the Node.js 22+ requirement in local development and CI.
2. Move project settings from package.json#pnpm and non-auth .npmrc files into pnpm-workspace.yaml.
3. Convert removed build settings into an explicit allowBuilds policy.
4. Regenerate or validate the lockfile on an isolated branch.
5. Inspect every override, patch, and resolved-version change as a policy change, not routine churn.
6. Keep a small CI assertion for the override that protects the highest-risk dependency.

The pnpm 11 upgrade is worthwhile, but it changes the boundary between application metadata and package-manager policy. Make that boundary explicit. Once configuration lives in the workspace file and CI checks the resulting graph, the next package-manager upgrade becomes a reviewable migration instead of a quiet dependency rollback.