From 543c7e4bae9e6357675f30e52b68bda5edff825b Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Sun, 1 Mar 2026 18:03:04 +0100 Subject: [PATCH] feat: use global virtual store for global packages and dlx (#10694) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: use global virtual store for global packages and dlx * fix(config): remove unnecessary virtualStoreDir override for global installs When the global virtual store is disabled, the default `node_modules/.pnpm` path works fine — no need to explicitly override it to `.pnpm`. --- .changeset/global-install-virtual-store.md | 6 ++++++ config/config/src/index.ts | 4 +++- exec/plugin-commands-script-runners/src/dlx.ts | 1 + exec/plugin-commands-script-runners/test/dlx.e2e.ts | 2 ++ 4 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 .changeset/global-install-virtual-store.md diff --git a/.changeset/global-install-virtual-store.md b/.changeset/global-install-virtual-store.md new file mode 100644 index 0000000000..8f00f19d51 --- /dev/null +++ b/.changeset/global-install-virtual-store.md @@ -0,0 +1,6 @@ +--- +"@pnpm/config": major +"pnpm": major +--- + +Global installs (`pnpm install -g`) and `pnpm dlx` now use the global virtual store by default. Packages are stored at `{storeDir}/links` instead of per-project `.pnpm` directories. This can be disabled by setting `enableGlobalVirtualStore: false` [#10694](https://github.com/pnpm/pnpm/pull/10694). diff --git a/config/config/src/index.ts b/config/config/src/index.ts index ab16544828..ebd37543e7 100644 --- a/config/config/src/index.ts +++ b/config/config/src/index.ts @@ -379,7 +379,9 @@ export async function getConfig (opts: { throw new PnpmError('CONFIG_CONFLICT_VIRTUAL_STORE_DIR_WITH_GLOBAL', 'Configuration conflict. "virtual-store-dir" may not be used with "global"') } - pnpmConfig.virtualStoreDir = '.pnpm' + if (pnpmConfig.enableGlobalVirtualStore == null) { + pnpmConfig.enableGlobalVirtualStore = true + } } else { pnpmConfig.dir = cwd if (!pnpmConfig.bin) { diff --git a/exec/plugin-commands-script-runners/src/dlx.ts b/exec/plugin-commands-script-runners/src/dlx.ts index 5c21007c68..2a321eaa0e 100644 --- a/exec/plugin-commands-script-runners/src/dlx.ts +++ b/exec/plugin-commands-script-runners/src/dlx.ts @@ -146,6 +146,7 @@ export async function handler ( fs.mkdirSync(cachedDir, { recursive: true }) await add.handler({ ...opts, + enableGlobalVirtualStore: opts.enableGlobalVirtualStore ?? true, bin: path.join(cachedDir, 'node_modules/.bin'), dir: cachedDir, lockfileDir: cachedDir, diff --git a/exec/plugin-commands-script-runners/test/dlx.e2e.ts b/exec/plugin-commands-script-runners/test/dlx.e2e.ts index 195bfd0d4d..08b43f552d 100644 --- a/exec/plugin-commands-script-runners/test/dlx.e2e.ts +++ b/exec/plugin-commands-script-runners/test/dlx.e2e.ts @@ -335,6 +335,7 @@ test('dlx builds the package that is executed', async () => { await dlx.handler({ ...DEFAULT_OPTS, + enableGlobalVirtualStore: false, dir: path.resolve('project'), storeDir: path.resolve('store'), cacheDir: path.resolve('cache'), @@ -361,6 +362,7 @@ test('dlx builds the packages passed via --allow-build', async () => { const allowBuild = ['@pnpm.e2e/install-script-example'] await dlx.handler({ ...DEFAULT_OPTS, + enableGlobalVirtualStore: false, allowBuild, dir: path.resolve('project'), storeDir: path.resolve('store'),