Skip to content

Support npm install-strategy=linked (.store directory layout) #595

Description

@manzoorwanijk

Bug report

When npm is configured with install-strategy=linked (an experimental feature in npm), packages are stored in node_modules/.store/<pkg>@<version>-<hash>/node_modules/<pkg>/ and symlinked into consuming packages' node_modules/. patch-package cannot find packages at these paths and fails to apply patches.

Current Behavior

With install-strategy=linked in .npmrc, running patch-package in postinstall fails with:

Error: Patch file found for package lighthouse which is not present at node_modules/@wordpress/e2e-test-utils-playwright/node_modules/lighthouse

The package exists, but at a different path:

node_modules/.store/lighthouse@12.2.2-E1oDY3hhcKvr16czLc4uyw/node_modules/lighthouse/

A symlink exists at the expected nested path, but it points into .store/:

packages/e2e-test-utils-playwright/node_modules/lighthouse ->
  ../../../node_modules/.store/lighthouse@12.2.2-E1oDY3hhcKvr16czLc4uyw/node_modules/lighthouse

This affects both nested patches (parent++child+version.patch) and, in monorepo/workspace setups, any packages whose dependencies are stored exclusively in .store/.

Expected behavior

patch-package should resolve the actual package location by following symlinks or by searching the .store/ directory when the traditional node_modules/ path doesn't contain the package directly.

Possible Solution

When looking up a package to patch, if the expected node_modules/<pkg> path is a symlink, follow it to find the real package directory and apply the patch there. Alternatively, add support for searching node_modules/.store/ for <pkg>@<version>-* entries.

This is related to #277 (monorepo hoisting) in that both involve packages not being at the path patch-package expects, but the root cause here is the npm linked install strategy's .store/ layout rather than workspace hoisting.

Context

npm's install-strategy=linked is an experimental feature that deduplicates packages by storing them in a content-addressed .store/ directory and creating symlinks. As this strategy matures and sees wider adoption, patch-package will need to handle this layout.

Our workaround is a custom apply-patches.mjs script that:

  1. Parses patch filenames to extract package name and version
  2. Looks up the package in node_modules/.store/<pkg>@<version>-*/node_modules/<pkg>/
  3. Rewrites diff paths in the patch to target the actual .store/ location
  4. Applies patches using git apply --ignore-whitespace

Your Environment

Software Version(s)
patch-package 8.0.0
npm 10.9.5
node 20.x+

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions