Subchapter 6.5
references/core-config.mdMarkdown7 KBView on GitHub
pnpm settings are split into two categories. Knowing where each goes is the single most important config concept in current pnpm:
| Category | Stored in | Format |
|---|
All pnpm/install settings (nodeLinker, hoistPattern, autoInstallPeers, overrides, catalog, …) | pnpm-workspace.yaml (project) and config.yaml (global) | YAML, camelCase keys |
Auth & registry credentials (_authToken, cert, key, …) | .npmrc (project, gitignored) and global rc | INI |
Important changes: pnpm no longer reads settings from the
pnpmfield ofpackage.json, and.npmrcis now used only for authentication/registry credentials. Everything else belongs inpnpm-workspace.yaml. Keys in YAML are camelCase (e.g.nodeLinker), not the kebab-case used by old.npmrcfiles.
Place at the workspace/project root. Even a single-package project uses this file for pnpm settings.
# Workspace packages (omit for a single-package repo)
packages:
- 'packages/*'
- 'apps/*'
- '!**/test/**'
# Common install settings (camelCase)
nodeLinker: isolated # isolated (default) | hoisted | pnp
autoInstallPeers: true
strictPeerDependencies: false
savePrefix: '^'
saveExact: false
hoistPattern:
- '*eslint*'
- '*babel*'
publicHoistPattern: []
shamefullyHoist: false
dedupeDirectDeps: false
resolutionMode: highest # highest | time-based | lowest-direct
# Centralized version management
catalog:
react: ^18.2.0
# Force dependency versions (root only)
overrides:
lodash: ^4.17.21
'foo@^1.0.0>bar': ^2.0.0
# Extend/patch broken package manifests
packageExtensions:
react-redux:
peerDependencies:
react-dom: '*'
# Peer dependency rules
peerDependencyRules:
ignoreMissing:
- '@babel/*'
allowedVersions:
react: '17 || 18'User-level non-auth settings live in a global YAML config.yaml:
$XDG_CONFIG_HOME/pnpm/config.yaml (if set)~/.config/pnpm/config.yaml~/Library/Preferences/pnpm/config.yaml~/AppData/Local/pnpm/config/config.yamlThe companion global rc file (same directory, named rc) holds only registry/auth settings.
There are no per-subproject .npmrc files anymore. Set per-package config via packageConfigs in the root pnpm-workspace.yaml:
packageConfigs:
# Map form: keyed by package name
project-1:
saveExact: true
project-2:
savePrefix: '~'
# Array form: pattern-matched rules
# - match: ['project-1', 'project-2']
# modulesDir: node_modules
# saveExact: trueKeep auth tokens out of the repo (gitignore the project .npmrc). Auth files, highest priority first:
<workspace root>/.npmrc (project, gitignored)<pnpm config>/auth.ini (written by pnpm login)~/.npmrc (fallback for npm compatibility)//registry.npmjs.org/:_authToken=${NPM_TOKEN}
@myorg:registry=https://npm.myorg.com/
//npm.myorg.com/:_authToken=${MYORG_TOKEN}Configure registries themselves (non-secret) in pnpm-workspace.yaml:
registries:
default: https://registry.npmjs.org/
'@my-org': https://private.example.com/
# Named registry aliases usable as a prefix, e.g. `pnpm add work:@corp/lib`
namedRegistries:
work: https://npm.work.example.com/Security: since v11, env-variable expansion is disabled for registry/proxy URLs and credential keys in the project
.npmrc(to stop a malicious repo from leaking secrets). Put dynamic-token lines in the user-level auth file instead.
# Writes to global config.yaml / rc by default
pnpm config set nodeVersion 22.0.0
pnpm config set --location=project nodeVersion 22.0.0 # writes pnpm-workspace.yaml
# JSON values create arrays/objects
pnpm config set --location=project --json allowBuilds '{"react": true}'
# get/list print JSON (no longer INI) since v11
pnpm config get nodeLinker
pnpm config get 'allowBuilds.react'
pnpm config listUse pnpm_config_* (or PNPM_CONFIG_*). pnpm no longer reads npm_config_*.
pnpm_config_save_exact=true pnpm add foo| Old (removed) | Replacement | Notes |
|---|---|---|
onlyBuiltDependencies, neverBuiltDependencies, ignoredBuiltDependencies, onlyBuiltDependenciesFile | allowBuilds: { name: true|false } | Single map controlling build-script approval. See supply-chain-security. |
managePackageManagerVersions, packageManagerStrict, packageManagerStrictVersion, COREPACK_ENABLE_STRICT | pmOnFail: download|ignore|warn|error | Behavior when running pnpm version ≠ declared one. |
useNodeVersion | devEngines.runtime (in package.json) | Runtime pinning. |
auditConfig.ignoreCves | auditConfig.ignoreGhsas | Use GHSA IDs. |
allowNonAppliedPatches | allowUnusedPatches | ignorePatchFailures removed (patches now always throw). |
package.json#pnpm field | pnpm-workspace.yaml | No longer read at all. |
{
"packageManager": "pnpm@10.0.0",
"devEngines": {
"packageManager": { "name": "pnpm", "version": ">=11.0.0 <12.0.0", "onFail": "download" },
"runtime": { "name": "node", "version": "22.x", "onFail": "download" }
}
}devEngines.packageManager supports ranges (resolved version stored in lockfile); packageManager requires an exact version. Override onFail without editing the manifest via pmOnFail / runtimeOnFail settings.
pnpm-workspace.yaml (camelCase) or global config.yaml; .npmrc is auth/registry only.package.json#pnpm and npm_config_* env vars are no longer read.packageConfigs for per-package settings inside a workspace.allowBuilds map; package-manager strictness is one pmOnFail setting.pnpm config get/list output JSON, and --location=project writes to pnpm-workspace.yaml.