1"use strict";(self.webpackChunk=self.webpackChunk||[]).push([["11377"],{1040(e,n,t){t.r(n),t.d(n,{metadata:()=>s,default:()=>h,frontMatter:()=>l,contentTitle:()=>o,toc:()=>c,assets:()=>a});var s=JSON.parse('{"id":"settings/store","title":"Store & Lockfile Settings","description":"Store Settings","source":"@site/versioned_docs/version-11.x/settings/store.md","sourceDirName":"settings","slug":"/settings/store","permalink":"/11.x/settings/store","draft":false,"unlisted":false,"editUrl":"https://github.com/pnpm/pnpm.io/edit/main/versioned_docs/version-11.x/settings/store.md","tags":[],"version":"11.x","lastUpdatedBy":"Zoltan Kochan","lastUpdatedAt":1788556519000,"frontMatter":{"id":"store","title":"Store & Lockfile Settings","sidebar_label":"Store & lockfile"},"sidebar":"docs","previous":{"title":"node_modules & hoisting","permalink":"/11.x/settings/node-modules"},"next":{"title":"Network & requests","permalink":"/11.x/settings/network"}}'),i=t(91987),r=t(67008);let l={id:"store",title:"Store & Lockfile Settings",sidebar_label:"Store & lockfile"},o,a={},c=[{value:"Store Settings",id:"store-settings",level:2},{value:"storeDir",id:"storedir",level:3},{value:"verifyStoreIntegrity",id:"verifystoreintegrity",level:3},{value:"useRunningStoreServer",id:"userunningstoreserver",level:3},{value:"strictStorePkgContentCheck",id:"strictstorepkgcontentcheck",level:3},{value:"frozenStore",id:"frozenstore",level:3},{value:"Lockfile Settings",id:"lockfile-settings",level:2},{value:"lockfile",id:"lockfile",level:3},{value:"preferFrozenLockfile",id:"preferfrozenlockfile",level:3},{value:"lockfileIncludeTarballUrl",id:"lockfileincludetarballurl",level:3},{value:"gitBranchLockfile",id:"gitbranchlockfile",level:3},{value:"mergeGitBranchLockfilesBranchPattern",id:"mergegitbranchlockfilesbranchpattern",level:3},{value:"peersSuffixMaxLength",id:"peerssuffixmaxlength",level:3}];function d(e){let n={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h2,{id:"store-settings",children:"Store Settings"}),"\n",(0,i.jsx)(n.h3,{id:"storedir",children:"storeDir"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Default:","\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["If the ",(0,i.jsx)(n.strong,{children:"$PNPM_HOME"})," env variable is set, then ",(0,i.jsx)(n.strong,{children:"$PNPM_HOME/store"})]}),"\n",(0,i.jsxs)(n.li,{children:["If the ",(0,i.jsx)(n.strong,{children:"$XDG_DATA_HOME"})," env variable is set, then ",(0,i.jsx)(n.strong,{children:"$XDG_DATA_HOME/pnpm/store"})]}),"\n",(0,i.jsxs)(n.li,{children:["On Windows: ",(0,i.jsx)(n.strong,{children:"~/AppData/Local/pnpm/store"})]}),"\n",(0,i.jsxs)(n.li,{children:["On macOS: ",(0,i.jsx)(n.strong,{children:"~/Library/pnpm/store"})]}),"\n",(0,i.jsxs)(n.li,{children:["On Linux: ",(0,i.jsx)(n.strong,{children:"~/.local/share/pnpm/store"})]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["Type: ",(0,i.jsx)(n.strong,{children:"path"})]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The location where all the packages are saved on the disk."}),"\n",(0,i.jsxs)(n.p,{children:["The store should be always on the same disk on which installation is happening,\nso there will be one store per disk. If there is a home directory on the current\ndisk, then the store is created inside it. If there is no home on the disk,\nthen the store is created at the root of the filesystem. For\nexample, if installation is happening on a filesystem mounted at ",(0,i.jsx)(n.code,{children:"/mnt"}),",\nthen the store will be created at ",(0,i.jsx)(n.code,{children:"/mnt/.pnpm-store"}),". The same goes for Windows\nsystems."]}),"\n",(0,i.jsx)(n.p,{children:"It is possible to set a store from a different disk but in that case pnpm will\ncopy packages from the store instead of hard-linking them, as hard links are\nonly possible on the same filesystem."}),"\n",(0,i.jsxs)(n.p,{children:["If no directory above the project accepts a hard link at all \u2014 an agent sandbox\nthat grants write access only to the project, or a container with just the\nproject bind-mounted writable \u2014 the store is created at ",(0,i.jsx)(n.code,{children:".pnpm-store"})," inside the\nproject. Putting it in the home directory there would either fail on a read-only\nhome or land on another volume, which copies every package instead of hard-linking\nit (",(0,i.jsx)(n.a,{href:"https://github.com/pnpm/pnpm/issues/13525",children:"#13525"}),")."]}),"\n",(0,i.jsx)(n.admonition,{type:"important",children:(0,i.jsxs)(n.p,{children:["The pnpm store is intended to be shared only between mutually trusted users, jobs, and processes. If you configure a shared ",(0,i.jsx)(n.code,{children:"storeDir"}),", protect it with filesystem permissions so untrusted users cannot write to it. The store is part of pnpm's trust domain: packages may be hard linked from it, and the store index (",(0,i.jsx)(n.code,{children:"index.db"}),") records the hashes used to verify cached files."]})}),"\n",(0,i.jsx)(n.h3,{id:"verifystoreintegrity",children:"verifyStoreIntegrity"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Default: ",(0,i.jsx)(n.strong,{children:"true"})]}),"\n",(0,i.jsxs)(n.li,{children:["Type: ",(0,i.jsx)(n.strong,{children:"Boolean"})]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["By default, if a file in the store has been modified, the content of this file is checked before linking it to a project's ",(0,i.jsx)(n.code,{children:"node_modules"}),". If ",(0,i.jsx)(n.code,{children:"verifyStoreIntegrity"})," is set to ",(0,i.jsx)(n.code,{children:"false"}),", files in the content-addressable store will not be checked during installation."]}),"\n",(0,i.jsx)(n.p,{children:"This setting helps detect accidental store corruption. It does not make a store that is writable by untrusted users safe, because an attacker who can write to the store can alter both cached package contents and the metadata used to verify them."}),"\n",(0,i.jsx)(n.h3,{id:"userunningstoreserver",children:"useRunningStoreServer"}),"\n",(0,i.jsx)(n.admonition,{type:"danger",children:(0,i.jsx)(n.p,{children:"Deprecated feature"})}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Default: ",(0,i.jsx)(n.strong,{children:"false"})]}),"\n",(0,i.jsxs)(n.li,{children:["Type: ",(0,i.jsx)(n.strong,{children:"Boolean"})]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Only allows installation with a store server. If no store server is running,\ninstallation will fail."}
1),"\n",(0,i.jsx)(n.h3,{id:"strictstorepkgcontentcheck",children:"strictStorePkgContentCheck"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Default: ",(0,i.jsx)(n.strong,{children:"true"})]}),"\n",(0,i.jsxs)(n.li,{children:["Type: ",(0,i.jsx)(n.strong,{children:"Boolean"})]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Some registries allow the exact same content to be published under different package names and/or versions. This breaks the validity checks of packages in the store. To avoid errors when verifying the names and versions of such packages in the store, you may set the ",(0,i.jsx)(n.code,{children:"strictStorePkgContentCheck"})," setting to ",(0,i.jsx)(n.code,{children:"false"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"frozenstore",children:"frozenStore"}),"\n",(0,i.jsx)(n.p,{children:"Added in: v11.7.0"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Default: ",(0,i.jsx)(n.strong,{children:"false"})]}),"\n",(0,i.jsxs)(n.li,{children:["Type: ",(0,i.jsx)(n.strong,{children:"Boolean"})]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Lets ",(0,i.jsx)(n.code,{children:"pnpm install"})," run against a package store that lives on a read-only filesystem \u2014 for example a ",(0,i.jsx)(n.a,{href:"https://nixos.org/",children:"Nix"})," store, a read-only bind mount, or an OCI image layer. When enabled, pnpm opens the store's SQLite ",(0,i.jsx)(n.code,{children:"index.db"})," in immutable mode (bypassing the WAL/",(0,i.jsx)(n.code,{children:"-shm"})," sidecar files that otherwise can't be created on a read-only directory) and suppresses every code path that would write to the store."]}),"\n",(0,i.jsxs)(n.p,{children:["Pair it with ",(0,i.jsx)(n.code,{children:"--offline"})," and ",(0,i.jsx)(n.code,{children:"--frozen-lockfile"})," against a fully-populated store:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"pnpm install --frozen-store --offline --frozen-lockfile\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The store must already contain everything the install needs, including the build output of any package whose lifecycle scripts are approved (or that has a patch applied). Under the ",(0,i.jsx)(n.a,{href:"/11.x/settings/node-modules#enableglobalvirtualstore",children:"global virtual store"}),", those package directories live inside the store, so if a required build is missing the install fails up front with ",(0,i.jsx)(n.code,{children:"ERR_PNPM_FROZEN_STORE_NEEDS_BUILD"})," \u2014 seed the store with those builds first. If the store is missing its content directory entirely, the install fails fast with ",(0,i.jsx)(n.code,{children:"ERR_PNPM_FROZEN_STORE_INCOMPLETE"})," rather than trying to initialize it."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"frozenStore"}
1)," is incompatible with ",(0,i.jsx)(n.code,{children:"--force"})," and with a configured pnpr server, since both write into the store. The ",(0,i.jsx)(n.a,{href:"/11.x/settings/build#sideeffectscache",children:"side effects cache"})," is not written either."]}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["The read-only store open requires Node.js >=22.15.0, >=23.11.0, or >=24.0.0. On older runtimes, ",(0,i.jsx)(n.code,{children:"--frozen-store"})," fails with ",(0,i.jsx)(n.code,{children:"ERR_PNPM_FROZEN_STORE_UNSUPPORTED_NODE"}),"."]})}),"\n",(0,i.jsx)(n.h2,{id:"lockfile-settings",children:"Lockfile Settings"}),"\n",(0,i.jsx)(n.h3,{id:"lockfile",children:"lockfile"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Default: ",(0,i.jsx)(n.strong,{children:"true"})]}),"\n",(0,i.jsxs)(n.li,{children:["Type: ",(0,i.jsx)(n.strong,{children:"Boolean"})]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["When set to ",(0,i.jsx)(n.code,{children:"false"}),", pnpm won't read or generate a ",(0,i.jsx)(n.code,{children:"pnpm-lock.yaml"})," file."]}),"\n",(0,i.jsx)(n.h3,{id:"preferfrozenlockfile",children:"preferFrozenLockfile"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Default: ",(0,i.jsx)(n.strong,{children:"true"})]}),"\n",(0,i.jsxs)(n.li,{children:["Type: ",(0,i.jsx)(n.strong,{children:"Boolean"})]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["When set to ",(0,i.jsx)(n.code,{children:"true"})," and the available ",(0,i.jsx)(n.code,{children:"pnpm-lock.yaml"})," satisfies the\n",(0,i.jsx)(n.code,{children:"package.json"})," dependencies directive, a headless installation is performed. A\nheadless installation skips all dependency resolution as it does not need to\nmodify the lockfile."]}),"\n",(0,i.jsx)(n.h3,{id:"lockfileincludetarballurl",children:"lockfileIncludeTarballUrl"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Default: ",(0,i.jsx)(n.strong,{children:"false"})]}),"\n",(0,i.jsxs)(n.li,{children:["Type: ",(0,i.jsx)(n.strong,{children:"Boolean"})]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Add the full URL to the package's tarball to every entry in ",(0,i.jsx)(n.code,{children:"pnpm-lock.yaml"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"gitbranchlockfile",children:"gitBranchLockfile"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Default: ",(0,i.jsx)(n.strong,{children:"false"})]}),"\n",(0,i.jsxs)(n.li,{children:["Type: ",(0,i.jsx)(n.strong,{children:"Boolean"})]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["When set to ",(0,i.jsx)(n.code,{children:"true"}),", the generated lockfile name after installation will be named\nbased on the current branch name to completely avoid merge conflicts. For example,\nif the current branch name is ",(0,i.jsx)(n.code,{children:"feature-foo"}),", the corresponding lockfile name will\nbe ",(0,i.jsx)(n.code,{children:"pnpm-lock.feature-foo.yaml"})," instead of ",(0,i.jsx)(n.code,{children:"pnpm-lock.yaml"}),". It is typically used\nin conjunction with the command line argument ",(0,i.jsx)(n.code,{children:"--merge-git-branch-lockfiles"})," or by\nsetting ",(0,i.jsx)(n.code,{children:"mergeGitBranchLockfilesBranchPattern"})," in the ",(0,i.jsx)(n.code,{children:"pnpm-workspace.yaml"})," file."]}),"\n",(0,i.jsx)(n.h3,{id:"mergegitbranchlockfilesbranchpattern",children:"mergeGitBranchLockfilesBranchPattern"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Default: ",(0,i.jsx)(n.strong,{children:"null"})]}),"\n",(0,i.jsxs)(n.li,{children:["Type: ",(0,i.jsx)(n.strong,{children:"Array or null"})]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["This configuration matches the current branch name to determine whether to merge\nall git branch lockfile files. By default, you need to manually pass the\n",(0,i.jsx)(n.code,{children:"--merge-git-branch-lockfiles"})," command line parameter. This configuration allows\nthis process to be automatically completed."]}),"\n",(0,i.jsx)(n.p,{children:"For instance:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"mergeGitBranchLockfilesBranchPattern:\n- main\n- release*\n"})}),"\n",(0,i.jsxs)(n.p,{children:["You may also exclude patterns using ",(0,i.jsx)(n.code,{children:"!"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"peerssuffixmaxlength",children:"peersSuffixMaxLength"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Default: ",(0,i.jsx)(n.strong,{children:"1000"})]}),"\n",(0,i.jsxs)(n.li,{children:["Type: ",(0,i.jsx)(n.strong,{children:"number"})]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Max length of the peer IDs suffix added to dependency keys in the lockfile. If the suffix is longer, it is replaced with a hash."})]})}function h(e={}){let{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},67008(e,n,t){t.d(n,{R:()=>l,x:()=>o});var s=t(71763);let i={},r=s.createContext(i);function l(e){let n=s.useContext(r);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:l(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.