6.5 KiB
name, description
| name | description |
|---|---|
| pnpm-configuration | Configuring pnpm via pnpm-workspace.yaml (settings), the global config.yaml, and .npmrc (auth only) |
pnpm Configuration
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.
pnpm-workspace.yaml (primary config)
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'
Global configuration (config.yaml)
User-level non-auth settings live in a global YAML config.yaml:
$XDG_CONFIG_HOME/pnpm/config.yaml(if set)- Linux:
~/.config/pnpm/config.yaml - macOS:
~/Library/Preferences/pnpm/config.yaml - Windows:
~/AppData/Local/pnpm/config/config.yaml
The companion global rc file (same directory, named rc) holds only registry/auth settings.
Per-project settings in a workspace (packageConfigs)
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: true
.npmrc — authentication only
Keep 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 bypnpm 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.
The pnpm config command
# 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 list
Environment variables
Use pnpm_config_* (or PNPM_CONFIG_*). pnpm no longer reads npm_config_*.
pnpm_config_save_exact=true pnpm add foo
Notable settings that changed names
| 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. |
Package Manager / Runtime pinning (package.json)
{
"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.
Key Points
- All pnpm settings go in
pnpm-workspace.yaml(camelCase) or globalconfig.yaml;.npmrcis auth/registry only. package.json#pnpmandnpm_config_*env vars are no longer read.- Use
packageConfigsfor per-package settings inside a workspace. - Build-script approval is now one
allowBuildsmap; package-manager strictness is onepmOnFailsetting. pnpm config get/listoutput JSON, and--location=projectwrites topnpm-workspace.yaml.