Edit (2026-05-19): I (the same agent that filed this issue in a prior session) audited the original write-up against the current pnpm v11 code and found that 3 of the 4 proposals would have been anti-parity. This body has been rewritten to describe the two actual gaps. The original framing is preserved at the bottom for the record. Fix: #11752.
Summary
Pacquet's config loader only reads pnpm-workspace.yaml (plus the auth/network subset of .npmrc). It misses two sources pnpm v11 does read:
<configDir>/config.yaml — the global config file pnpm reads from ~/.config/pnpm/config.yaml on Linux, ~/Library/Preferences/pnpm/config.yaml on macOS, %LOCALAPPDATA%/pnpm/config/config.yaml on Windows (plus $XDG_CONFIG_HOME/pnpm/config.yaml when set). See upstream's index.ts:228 / 297-316 and getConfigDir.
PNPM_CONFIG_* / pnpm_config_* env vars — pnpm reads these for every key in its schema via parseEnvVars at index.ts:471-488. Pacquet previously honored only NPM_CONFIG_WORKSPACE_DIR.
When a user has enableGlobalVirtualStore: true set globally (in config.yaml or via env var) and runs an install in a project whose pnpm-workspace.yaml doesn't repeat the setting, pnpm sees it but pacquet doesn't — pacquet falls back to its built-in default (false) and the install lands in the local virtual store, not the global one.
Surfaced while wiring up pacquet delegation for pnpm install --frozen-lockfile via configDependencies (#11723, #11734).
Repro
- In
~/.config/pnpm/config.yaml (or platform equivalent), set:
enableGlobalVirtualStore: true
- Create a project with a
pnpm-workspace.yaml that does not declare enableGlobalVirtualStore, plus a configDependencies: { pacquet: \"^0.1.0\" }.
- Run
pnpm install --frozen-lockfile.
Expected: pacquet materializes packages into the global virtual store (same as pnpm would).
Actual: pacquet materializes into the local node_modules/.pnpm/ store, because it never saw the setting.
What pnpm v11 actually reads (audit)
This is the part the original write-up got wrong. For the record:
| Source |
What pnpm v11 reads |
Filter |
.npmrc (project + user) |
auth + network keys only |
isNpmrcReadableKey — auth keys + the network keys proxy / https-proxy / no-proxy / http-proxy / local-address / strict-ssl (network keys retained for npm migration only) |
npm_config_* / NPM_CONFIG_* env vars |
only npm_config_userconfig, as a low-priority auth-file fallback |
index.ts:719-722 |
~/.pnpmrc / ~/.config/pnpm/rc |
nothing — these files aren't read |
— |
<configDir>/config.yaml |
full schema, filtered to isConfigFileKey |
configFileKey.ts:187 |
PNPM_CONFIG_* / pnpm_config_* env vars |
full schema, both case forms |
env.ts:185-195 |
pnpm-workspace.yaml |
full schema (no filter) |
— |
Cascade order (lowest to highest precedence): defaults < .npmrc (auth/network only) < <configDir>/config.yaml < pnpm-workspace.yaml < PNPM_CONFIG_* env < CLI.
What this issue is asking for (revised)
- Read
<configDir>/config.yaml, layered between .npmrc and pnpm-workspace.yaml, with workspace-only keys filtered out to mirror isConfigFileKey.
- Read
PNPM_CONFIG_* / pnpm_config_* env vars for the whole settings surface, applied after pnpm-workspace.yaml so env wins over yaml.
Per pacquet's cardinal rule, behavior must match pnpm exactly — this is a real parity gap, not an MVP scoping decision.
Workaround (for now)
Repeat the setting in the project's pnpm-workspace.yaml. Pacquet does read that.
Original write-up (preserved for reference)
The original issue body claimed pnpm reads non-auth settings from .npmrc, ~/.pnpmrc, ~/.config/pnpm/rc, and npm_config_* env vars, and proposed pacquet do the same. Three of those four are anti-parity:
- pnpm does not read non-auth/non-network keys from
.npmrc.
- pnpm does not read
~/.pnpmrc or ~/.config/pnpm/rc — neither file is part of pnpm's lookup chain.
- pnpm does not read general
npm_config_* env vars (only the narrow npm_config_userconfig shim for the auth file).
Implementing the original proposal would have made pacquet honor settings pnpm v11 ignores, which diverges from the project's parity goal. The two genuine gaps are the ones described above.
Written by an agent (Claude Code, claude-opus-4-7).
Summary
Pacquet's config loader only reads
pnpm-workspace.yaml(plus the auth/network subset of.npmrc). It misses two sources pnpm v11 does read:<configDir>/config.yaml— the global config file pnpm reads from~/.config/pnpm/config.yamlon Linux,~/Library/Preferences/pnpm/config.yamlon macOS,%LOCALAPPDATA%/pnpm/config/config.yamlon Windows (plus$XDG_CONFIG_HOME/pnpm/config.yamlwhen set). See upstream'sindex.ts:228 / 297-316andgetConfigDir.PNPM_CONFIG_*/pnpm_config_*env vars — pnpm reads these for every key in its schema viaparseEnvVarsatindex.ts:471-488. Pacquet previously honored onlyNPM_CONFIG_WORKSPACE_DIR.When a user has
enableGlobalVirtualStore: trueset globally (inconfig.yamlor via env var) and runs an install in a project whosepnpm-workspace.yamldoesn't repeat the setting, pnpm sees it but pacquet doesn't — pacquet falls back to its built-in default (false) and the install lands in the local virtual store, not the global one.Surfaced while wiring up pacquet delegation for
pnpm install --frozen-lockfileviaconfigDependencies(#11723, #11734).Repro
~/.config/pnpm/config.yaml(or platform equivalent), set:pnpm-workspace.yamlthat does not declareenableGlobalVirtualStore, plus aconfigDependencies: { pacquet: \"^0.1.0\" }.pnpm install --frozen-lockfile.Expected: pacquet materializes packages into the global virtual store (same as pnpm would).
Actual: pacquet materializes into the local
node_modules/.pnpm/store, because it never saw the setting.What pnpm v11 actually reads (audit)
This is the part the original write-up got wrong. For the record:
.npmrc(project + user)isNpmrcReadableKey— auth keys + the network keysproxy / https-proxy / no-proxy / http-proxy / local-address / strict-ssl(network keys retained for npm migration only)npm_config_*/NPM_CONFIG_*env varsnpm_config_userconfig, as a low-priority auth-file fallbackindex.ts:719-722~/.pnpmrc/~/.config/pnpm/rc<configDir>/config.yamlisConfigFileKeyconfigFileKey.ts:187PNPM_CONFIG_*/pnpm_config_*env varsenv.ts:185-195pnpm-workspace.yamlCascade order (lowest to highest precedence): defaults <
.npmrc(auth/network only) <<configDir>/config.yaml<pnpm-workspace.yaml<PNPM_CONFIG_*env < CLI.What this issue is asking for (revised)
<configDir>/config.yaml, layered between.npmrcandpnpm-workspace.yaml, with workspace-only keys filtered out to mirrorisConfigFileKey.PNPM_CONFIG_*/pnpm_config_*env vars for the whole settings surface, applied afterpnpm-workspace.yamlso env wins over yaml.Per pacquet's cardinal rule, behavior must match pnpm exactly — this is a real parity gap, not an MVP scoping decision.
Workaround (for now)
Repeat the setting in the project's
pnpm-workspace.yaml. Pacquet does read that.Original write-up (preserved for reference)
The original issue body claimed pnpm reads non-auth settings from
.npmrc,~/.pnpmrc,~/.config/pnpm/rc, andnpm_config_*env vars, and proposed pacquet do the same. Three of those four are anti-parity:.npmrc.~/.pnpmrcor~/.config/pnpm/rc— neither file is part of pnpm's lookup chain.npm_config_*env vars (only the narrownpm_config_userconfigshim for the auth file).Implementing the original proposal would have made pacquet honor settings pnpm v11 ignores, which diverges from the project's parity goal. The two genuine gaps are the ones described above.
Written by an agent (Claude Code, claude-opus-4-7).