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/core-store.md
1---2name: pnpm-store3description: Content-addressable storage system that makes pnpm fast and disk-efficient4---56# pnpm Store78pnpm uses a content-addressable store to save disk space and speed up installations. All packages are stored once globally and hard-linked to project `node_modules`.910## How It Works11121. **Global Store**: Packages are downloaded once to a central store132. **Hard Links**: Projects link to store instead of copying files143. **Content-Addressable**: Files are stored by content hash, deduplicating identical files1516### Storage Layout1718```19<store-dir>/ # Global content-addressable store (pnpm store path)20└── files/21└── <hash>/ # Files stored by content hash2223project/24└── node_modules/25├── .pnpm/ # Virtual store (hard links to global store)26│ ├── [email protected]/27│ │ └── node_modules/28│ │ └── lodash/29│ └── [email protected]/30│ └── node_modules/31│ ├── express/32│ └── <deps>/ # Flat structure for dependencies33├── lodash -> .pnpm/[email protected]/node_modules/lodash34└── express -> .pnpm/[email protected]/node_modules/express35```3637## Store Commands3839```bash40# Show store location41pnpm store path4243# Remove unreferenced packages44pnpm store prune4546# Check store integrity47pnpm store status4849# Add package to store without installing50pnpm store add <pkg>51```5253## Configuration5455Store/linker settings live in `pnpm-workspace.yaml` (camelCase), not `.npmrc`.5657### Store Location5859```yaml title="pnpm-workspace.yaml"60storeDir: ~/.local/share/pnpm/store61```6263The default store path is OS-specific (e.g. `~/.local/share/pnpm/store` on Linux, `~/Library/pnpm/store` on macOS). Find it with `pnpm store path`.6465### Virtual Store6667The virtual store (`.pnpm` in `node_modules`) contains hard links to the global store:6869```yaml title="pnpm-workspace.yaml"70virtualStoreDir: node_modules/.pnpm71virtualStoreDirMaxLength: 60 # lower this for long-path issues on Windows72nodeLinker: hoisted # alternative flat layout73```7475## Disk Space Benefits7677pnpm saves significant disk space:7879- **Deduplication**: Same package version stored once across all projects80- **Content deduplication**: Identical files across different packages stored once81- **Hard links**: No copying, just linking8283### Check disk usage8485```bash86# Compare actual vs apparent size87du -sh node_modules # Apparent size88du -sh --apparent-size node_modules # With hard links counted89```9091## Global Virtual Store9293With `enableGlobalVirtualStore: true`, projects skip the per-project `node_modules/.pnpm` directory entirely; their `node_modules` contains only symlinks into one shared virtual store at `<store-path>/links/`, keyed by dependency-graph hash. In pnpm v11 it is the default for `pnpm dlx`/`pnx` and global installs; for project installs it is still opt-in. See `features-global-virtual-store` for details and the git-worktrees multi-agent workflow.9495```yaml title="pnpm-workspace.yaml"96enableGlobalVirtualStore: true97```9899## Node Linker Modes100101Configure how `node_modules` is structured (`nodeLinker` in `pnpm-workspace.yaml`):102103```yaml title="pnpm-workspace.yaml"104nodeLinker: isolated # default: symlinked virtual store (strict, no phantom deps)105# nodeLinker: hoisted # flat node_modules (npm-like) for tools that dislike symlinks106# nodeLinker: pnp # Plug'n'Play, no node_modules (set `symlink: false` too)107```108109### Isolated Mode (Default)110111- Strict dependency resolution112- No phantom dependencies113- Packages can only access declared dependencies114115### Hoisted Mode116117- Flat `node_modules` like npm118- For compatibility with tools that don't support symlinks119- Loses strictness benefits120121## Side Effects Cache122123Cache build outputs for native modules (enabled by default):124125```yaml title="pnpm-workspace.yaml"126sideEffectsCache: true127sideEffectsCacheReadonly: false # only read the cache, don't create it128```129130## Read-only / Frozen Store131132`frozenStore: true` (v11.7+) lets `pnpm install` run against a read-only store (Nix store, read-only bind mount, OCI layer). Pair with `--offline --frozen-lockfile`; the store must already contain everything, including approved build outputs.133134```bash135pnpm install --frozen-store --offline --frozen-lockfile136```137138## Shared Store Across Machines139140For CI/CD, you can share the store:141142```yaml143# GitHub Actions example144- uses: pnpm/action-setup@v4145with:146run_install: false147148- name: Get pnpm store directory149shell: bash150run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV151152- uses: actions/cache@v4153with:154path: ${{ env.STORE_PATH }}155key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}156```157158## Troubleshooting159160### Store corruption161```bash162# Verify and fix store163pnpm store status164pnpm store prune165```166167### Hard link issues (network drives, Docker)168```yaml title="pnpm-workspace.yaml"169# auto (default) tries clone -> hardlink -> copy170packageImportMethod: copy171```172173### Permission issues174```bash175# Fix store permissions (find the path with `pnpm store path`)176chmod -R u+w "$(pnpm store path)"177```178179<!--180Source references:181- https://pnpm.io/symlinked-node-modules-structure182- https://pnpm.io/cli/store183- https://pnpm.io/settings#storedir184- https://pnpm.io/global-virtual-store185-->186