From the skill’s files
Taken from the skill’s own files (its description, section headings and stated usage). Not an AutoGineer summary, and not written by the author as one.
Node.js package manager with strict dependency resolution. Use when running pnpm specific commands, configuring workspaces via pnpm-workspace.yaml, or managing dependencies with catalogs, patches, overrides, config dependencies, or the global virtual store. pnpm is a fast, disk space efficient package manager. It uses a content-addressable store to deduplicate packages across all projects on a machine, and enforces strict dependency resolution by default, preventing phantom dependencies.
What it does
- Core
- Features
- Best Practices
When to use it
- Use when running pnpm specific commands, configuring workspaces via pnpm-workspace.yaml, or managing dependencies with catalogs, patches, overrides, config dependencies, or the global virtual store.
Advantages
The skill’s files do not state this.
Usage examples
The skill’s files do not state this.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/antfu/pnpm/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip pnpm.zip -d .agents/skills
Documentation by Anthony Fu
pnpm is a fast, disk space efficient package manager. It uses a content-addressable store to deduplicate packages across all projects on a machine, and enforces strict dependency resolution by default, preventing phantom dependencies.
pnpm v12 is a Rust rewrite of v11: stable, and keeps v11's commands, flags, settings, and lockfile format — so most guidance here applies to both. A handful of v12 behaviors differ (git deps resolve via HTTPS, project-aware global bins, other package managers, packageImportMethod: auto hardlinks first on Linux) — see best-practices-migration.
Configuration model (important): pnpm settings live in pnpm-workspace.yaml (and the global config.yaml) using camelCase keys. .npmrc is used only for authentication/registry credentials, and the pnpm field of package.json is no longer read. When working in a pnpm project, check pnpm-workspace.yaml for settings/workspace structure and .npmrc only for auth. Always use --frozen-lockfile (or pnpm ci) in CI.
The skill is based on pnpm 12.18, generated at 2026-11-05. It covers v11+v12 behavior (config split, config includes, isolated global packages,
allowBuilds,pmOnFail, global virtual store, native release management, workspace task orchestration, and experimental Python/Cargo support) where current docs describe them.
Core
| Topic | Description | Reference |
|---|---|---|
| CLI Commands | install/add/remove/update, run, dlx/pnx, workspace, runtime, publishing (version, view, sbom, stage) | core-cli |
| Configuration | pnpm-workspace.yaml settings (camelCase), global config.yaml, config includes, packageConfigs, auth (.npmrc, auth.ini) | core-config |
| Workspaces | Monorepo support: filtering, workspace protocol, shared lockfile, packageConfigs | core-workspaces |
| Store | Content-addressable store, virtual store, node linker modes (incl. loaded/store loader), frozen/read-only store | core-store |
Features
| Topic | Description | Reference |
|---|---|---|
| Catalogs | Centralized dependency versions; catalogMode, catalog: in overrides | features-catalogs |
| Overrides | Force versions (incl. transitive & peer deps); packageExtensions | features-overrides |
| Patches | Modify third-party packages; patchedDependencies in pnpm-workspace.yaml | features-patches |
| Aliases | Install under custom names (npm:) and registry aliases (namedRegistries) | features-aliases |
| Hooks | .pnpmfile.mjs hooks (readPackage, updateConfig, beforePacking), finders, resolvers/fetchers | features-hooks |
| Peer Dependencies | Auto-install, strict mode, rules, dedupePeers, peers check | features-peer-deps |
| Config Dependencies | Share hooks/settings/catalogs/patches across repos via configDependencies | features-config-dependencies |
| Global Virtual Store & Shims | Shared node_modules, git-worktree multi-agent setups, isolated global packages, project-aware bins, other package managers | features-global-virtual-store |
| Supply-Chain Security | Build approval (allowBuilds), permissions and agent skills, minimumReleaseAge, trustPolicy, lockfile integrity | features-supply-chain-security |
| Task Orchestration | Cross-project task graphs (tasks/dependsOn), concurrency groups, priority, pnpm pipeline | features-task-orchestration |
| Release Management | Native versioning: pnpm change/version -r/lane, lanes, epics, fixed groups | features-versioning |
| Multi-Ecosystem | Python (pypi:) and Cargo (crate:) dependencies alongside npm (experimental) | features-multi-ecosystem |
Best Practices
| Topic | Description | Reference |
|---|---|---|
| CI/CD Setup | GitHub Actions, GitLab, Docker, pnpm ci, store caching, frozen lockfiles | best-practices-ci |
| Migration | npm/Yarn → pnpm, phantom deps, and pnpm v10 → v11 → v12 upgrade notes | best-practices-migration |
| Performance | Install optimizations, allowBuilds, global virtual store, workspace parallelization | best-practices-performance |
Files
- ATTRIBUTION.mdAdded by AutoGineer889 B
- GENERATION.md134 B
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md5.1 KiB
- references/best-practices-ci.md9.7 KiB
- references/best-practices-migration.md9.9 KiB
- references/best-practices-performance.md6.0 KiB
- references/core-cli.md11.3 KiB
- references/core-config.md12.8 KiB
- references/core-store.md10.7 KiB
- references/core-workspaces.md6.6 KiB
- references/features-aliases.md4.4 KiB
- references/features-catalogs.md5.0 KiB
- references/features-config-dependencies.md4.2 KiB
- references/features-global-virtual-store.md10.0 KiB
- references/features-hooks.md8.9 KiB
- references/features-multi-ecosystem.md6.2 KiB
- references/features-overrides.md5.5 KiB
- references/features-patches.md5.0 KiB
- references/features-peer-deps.md5.9 KiB
- references/features-supply-chain-security.md7.7 KiB
- references/features-task-orchestration.md6.8 KiB
- references/features-versioning.md5.5 KiB
references/core-config.md
name: pnpm-configuration description: 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, TLS, proxy, local-address (_authToken, cert, key, …) | .npmrc (project, gitignored) and global auth.ini | INI |
Important changes: pnpm no longer reads settings from the
pnpmfield ofpackage.json(a setting found there is ignored with a warning), 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.
The upstream settings reference is now split into pages by area —
settings/build,settings/cli,settings/dependency-resolution,settings/network,settings/node-modules,settings/store,settings/peer-dependencies,settings/versioning,settings/other— but they are all the same camelCase keys inpnpm-workspace.yaml.
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.yamlmacOS:
~/Library/Preferences/pnpm/config.yamlWindows:
%LOCALAPPDATA%\pnpm\config\config.yaml
Auth INI settings go in auth.ini in the same directory (written by pnpm login/pnpm config set of auth keys).
Project-only settings (structure of node_modules/workspace: nodeLinker, hoistPattern, publicHoistPattern, shamefullyHoist, linkWorkspacePackages, ...) must be in pnpm-workspace.yaml; in the global config.yaml they are ignored with a warning, and pnpm config set --global fails with ERR_PNPM_CONFIG_SET_UNSUPPORTED_YAML_CONFIG_KEY. Machine-level settings (storeDir, cacheDir, packageImportMethod, minimumReleaseAge, network) may be global. Share project-only settings across repos via a config dependency. Conversely, machine-state settings (bin, configDir, dir, globalBinDir, globalDir, macosBackup, npmrcAuthFile, pnpmHomeDir, scope, stateDir, userconfig, workspaceDir, ci, symlinkedLockfileTargetDirs, tools, ...) are ignored in a project's pnpm-workspace.yaml (pnpm config set --location=project fails with ERR_PNPM_CONFIG_SET_NOT_A_PROJECT_SETTING). cacheDir/storeDir are fine.
Splitting settings across files (config includes, v12.15+)
The root pnpm-workspace.yaml can delegate settings to other YAML files and to config dependencies via include, so protected files (CODEOWNERS, read-only mounts, agent sandboxes) hold security settings while routine ones (catalogs) live in freely editable files.
configDependencies:
'@acme/pnpm-policy': 3.1.0
pnpmfile: [] # no pnpmfile: stop auto-picking up a new .pnpmfile.mjs
include:
./config/security.yaml: '*' # any setting no other source owns
./config/catalog.yaml: [catalog] # list = permits AND reserves these settings
./patches/patches.yaml: [patchedDependencies]
'@acme/pnpm-policy': [minimumReleaseAge, trustPolicy] # config dep: list requiredSources: local
./or../.yaml/.ymlfiles (must exist; no globs/absolute/URLs) or a name declared inconfigDependencies. Only the root file may defineinclude;includecannot be delegated. Bad sources:ERR_PNPM_INVALID_WORKSPACE_INCLUDE.One owner per setting: a duplicate claim fails with
ERR_PNPM_DUPLICATE_SETTING; defining a non-delegated setting in a file fails withERR_PNPM_SETTING_NOT_DELEGATED. A delegated setting its owner omits is simply unset by the project.Catalogs:
catalog/catalogs.default,catalogs.<name>, orcatalogs(all). Entries of one catalog are never split.Relative paths inside an included file (
patchedDependencies,patchesDir,packages,file:/link:entries, ...) are relative to that file.Writes (
pnpm addwith catalog,approve-builds,patch-commit,audit --fix,config set --location project) go to the owning file; unowned settings go topnpm-workspace.yaml; config-dep-owned settings fail (ERR_PNPM_SETTING_OWNED_BY_CONFIG_DEPENDENCY).A config dependency supplies settings declaratively through
"pnpm": { "config": "./config.yaml" }in itspackage.json(file must stay inside the package, elseERR_PNPM_INVALID_CONFIG_DEPENDENCY_ENTRY). Not delegable to config deps:configDependencies,pnpmfile,globalPnpmfile,bootConfig,packages,scriptShell, path settings (patchedDependencies,storeDir,lockfileDir).bootConfigsets the policy used when installing config dependencies / the pnpm version (before their settings load): acceptsminimumReleaseAge,minimumReleaseAgeExclude,minimumReleaseAgeStrict,minimumReleaseAgeIgnoreMissingTime,trustPolicy,trustPolicyExclude,trustPolicyIgnoreAfter. Unset falls back to the regular value.An
updateConfighook runs after merge and can still change anything.
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 INI files, highest priority first (override the project-trusted file with npmrcAuthFile):
<workspace root>/.npmrc(project, gitignored)<pnpm config>/auth.ini(written bypnpm loginsince v12.16, and bypnpm config setof auth keys)~/.npmrc(fallback for npm compatibility)
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
@myorg:registry=https://npm.myorg.com/
//npm.myorg.com/:_authToken=${MYORG_TOKEN}Structured _auth (v11.10+, for CI)
An alternative to many //host/:_authToken=… lines, keyed by registry URL. Honored only from the global config.yaml and the pnpm_config__auth (or PNPM_CONFIG__AUTH) env var - ignored in a project .npmrc/pnpm-workspace.yaml. authToken is the only field and may use ${NAME}. Each entry also routes packages: "@" sets the default registry, "@org" routes that scope; priority is CLI flags, then pnpm_config__auth (overrides registry/registries), then global config.yaml (only where no registry/registries chooses). pnpm login wrote here in v12.1-12.15; since v12.16 it saves to auth.ini.
_auth:
https://registry.npmjs.org:
"@": { authToken: npm-token } # @ = registry-wide/default
"@org": { authToken: org-token } # scope-bound on the same hostexport pnpm_config__auth='{"https://registry.npmjs.org":{"@":{"authToken":"npm-token"}}}'Configure registries themselves (non-secret) in pnpm-workspace.yaml:
registries:
default: https://registry.npmjs.org/
'@my-org': https://private.example.com/
# Newer shape: keyed by URL, with scopes and a bare-specifier prefix (`pnpm add work:@corp/lib`)
# registries:
# https://npm.work.example.com/:
# scopes: ['@corp']
# prefix: work(namedRegistries is deprecated in favor of prefix in registries.)
Per-scope tokens: //npm.pkg.github.com/:_authToken plus scoped keys; tokenHelper=/abs/path (user-level auth files only, absolute path, no args) prints a fresh token for expiring credentials.
Security: env-variable expansion is disabled for registry/proxy URLs,
//keys, and credentials (_authToken,_auth,_password,username,tokenHelper,cert,key) in the project.npmrc(such settings are ignored with a warning). Put${NPM_TOKEN}lines inauth.ini/~/.npmrc, use_auth, or pass env varpnpm_config_//registry.npmjs.org/:_authToken=...viaenv(shells cannotexportthat name). Last resort for trusted CI:PNPM_CONFIG_NPMRC_AUTH_FILE=.npmrc. Likewise env vars are not expanded inregistry/registries/userAgentvalues inpnpm-workspace.yaml.
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 prints strings/numbers/booleans as plain text, objects/arrays as JSON (`--json` forces JSON); list prints JSON
pnpm config get nodeLinker
pnpm config get 'allowBuilds.react'
pnpm config listEnvironment variables
Use pnpm_config_* (or PNPM_CONFIG_*). pnpm no longer reads npm_config_*, except NPM_CONFIG_WORKSPACE_DIR, npm_config_userconfig, and URL-scoped credentials (npm_config_//host/:_authToken). In config files, ${NAME}, ${NAME-fallback}, ${NAME:-fallback} expand; ${NAME?} expands to empty silently (v12.7+).
pnpm_config_save_exact=true pnpm add fooNotable 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": "[email protected]",
"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. Declaring packageManager with another manager (npm, yarn, bun) is allowed. With no lockfile pin yet, pnpm records the running version if it satisfies the range and is older than minimumReleaseAge, else the newest old-enough 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.
<!-- Source references: - https://pnpm.io/settings - https://pnpm.io/configuring - https://pnpm.io/npmrc - https://pnpm.io/pnpm-workspace_yaml - https://pnpm.io/package_json - https://pnpm.io/cli/config - https://pnpm.io/config-includes -->
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs Node.js
Security
What our scanner noticed· Low risk
- Instructions that use the network
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- Anthony Fu
- Publisher
- Anthony Fu (Community)
- Source
- antfu/skills · skills/pnpm · commit f63e9ec
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE.md)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Anthony Fu or Anthony Fu.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download pnpm.zip