ds300 / ds300/patch-package

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

Open
#595 3 comments 1 reaction 0 assignees View on GitHub
Dominant language
TypeScript
Stars
11.2k
Forks
325
PR merge metrics
No merged PRs in 30d

Description

## Bug report

When npm is configured with `install-strategy=linked` ([an experimental feature in npm](https://docs.npmjs.com/cli/v11/commands/npm-install#install-strategy)), packages are stored in `node_modules/.store/@-/node_modules//` 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/` 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 `@-*` 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/@-*/node_modules//`
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+ |

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.