Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
pnpm 10.x reference skill covering workspaces, catalogs, patches, peer deps, overrides, and CI/CD caching strategies.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/features-global-virtual-store.md
1---2name: pnpm-global-virtual-store3description: Global virtual store for shared node_modules across checkouts, git-worktree multi-agent setups, and isolated global packages4---56# Global Virtual Store, Git Worktrees & Global Packages78## Global virtual store910By default each project has its own `node_modules/.pnpm` virtual store containing hard links to the content-addressable store. With the **global virtual store** enabled, pnpm keeps one shared virtual store at `<store-path>/links/` (find it via `pnpm store path`), and each project's `node_modules` contains only **symlinks** into it.1112```yaml title="pnpm-workspace.yaml"13enableGlobalVirtualStore: true14```1516```17# Default (per-project .pnpm with hard links)18project-a/node_modules/lodash -> .pnpm/[email protected]/node_modules/lodash1920# Global virtual store (symlink to shared location)21project-a/node_modules/lodash -> <store>/links/@/lodash/4.17.21/<hash>/node_modules/lodash22project-b/node_modules/lodash -> <store>/links/@/lodash/4.17.21/<hash>/node_modules/lodash # same target23```2425- **Package identity = hash of the dependency graph.** Two projects with the same `[email protected]` and the same transitive tree point at the exact same directory (NixOS-style). Different peers ⇒ separate entries.26- **Near-zero per-project cost** and **instant installs** once a version is in the store.27- In **pnpm v11** it is the default for `pnpm dlx`/`pnx` and global installs; for **project** installs it is still **opt-in/experimental**.2829### Limitations3031- **CI:** auto-disabled (no warm cache to benefit from).32- **Trust:** the store is shared writable state — only for mutually trusting projects/users/jobs; protect the path with filesystem permissions.33- **ESM hoisting:** relies on `NODE_PATH`, which Node ignores for ESM imports. If ESM deps import undeclared packages, resolution fails. Fix with `packageExtensions` or the `@pnpm/plugin-esm-node-path` config dependency.3435## Git worktrees for multi-agent development3637Git worktrees let you check out many branches simultaneously, each in its own directory, sharing one `.git` object store. Combined with the global virtual store, every worktree gets a fully functional `node_modules` that is almost free on disk — ideal for running multiple AI agents in parallel.3839```sh40# Bare repo as the hub, one worktree per branch/agent41git clone --bare https://github.com/your-org/your-monorepo.git your-monorepo42cd your-monorepo43git worktree add ./main main44git worktree add ./feature-auth feat/auth45git worktree add ./fix-api fix/api-error46```4748```yaml title="pnpm-workspace.yaml"49packages:50- 'packages/*'51enableGlobalVirtualStore: true52```5354```sh55cd main && pnpm install # first install fills the global store56cd ../feature-auth && pnpm install # subsequent worktrees: nearly instant, just symlinks57```5859Each worktree has its own `node_modules` tree (so agents can install different versions on different branches without conflict), but all package contents come from the one shared store. Remove a worktree with `git worktree remove ./feature-auth`.6061> The pnpm repo itself uses this setup and ships helper scripts (`pnpm worktree:new <branch|pr>`). Assumes all worktrees/agents share the same trust boundary.6263## Global packages (v11 isolated installs)6465`pnpm add -g` was redesigned in v11 for isolation. Each globally installed package (or group) gets its own install directory with its own `package.json`, `node_modules/`, and lockfile, so global tools can't break each other via peer/hoisting conflicts. Installs are stored at `{pnpmHomeDir}/global/v11/{hash}/` and share the global virtual store.6667```sh68pnpm add -g typescript prettier # space-separated = separate isolated installs each69pnpm add -g eslint,prettier # comma-separated = ONE shared install group70pnpm remove -g eslint # removes only eslint's group71pnpm add -g --allow-build=esbuild esbuild # pre-approve build scripts72pnpm list -g # always works at depth 073pnpm bin -g # global bin dir = $PNPM_HOME/bin74```7576- `pnpm install -g` (no args) is **not** supported — use `pnpm add -g <pkg>`.77- Binaries live in `$PNPM_HOME/bin` (not `$PNPM_HOME` directly). Run `pnpm setup` after upgrading to put it on PATH.78- Register a local package's bins globally with `pnpm add -g .` (replaces `pnpm link --global`).79- `pnpm list -g --depth=<n>` (n>0) only works for a single install group.8081## Key Points8283- `enableGlobalVirtualStore: true` ⇒ `node_modules` is symlinks into one shared, hash-addressed store.84- Best for many checkouts of the same repo (git worktrees, parallel agents); auto-disabled in CI.85- Watch out for ESM packages importing undeclared deps (NODE_PATH limitation).86- v11 global installs are isolated per package; comma-list to share a group; bins live in `$PNPM_HOME/bin`.8788<!--89Source references:90- https://pnpm.io/global-virtual-store91- https://pnpm.io/git-worktrees92- https://pnpm.io/global-packages93- https://pnpm.io/settings#enableglobalvirtualstore94-->95