Commit 5dd695c
authored
RFC: Native Dependency Patching (#862)
## Summary
Adds first-class, install-time patching of installed dependencies to the
npm CLI, on parity with `pnpm patch`, `yarn patch`, and `bun patch`.
Introduces a new `npm patch` command with subcommands `add` / `commit` /
`update` / `ls` / `rm` (with `npm patch <pkg>` as shorthand for `npm
patch add <pkg>`), a `patchedDependencies` field in `package.json`, and
a `patched.{path,integrity}` record in `package-lock.json`
(`lockfileVersion: 4`). Patches apply during Arborist's reify step,
uniformly across every supported `install-strategy` (`hoisted`,
`nested`, `shallow`, `linked`).
## Why now
The third-party `patch-package` is currently the only path to dependency
patching for npm users, and it is structurally limited:
- **Silently disabled by `--ignore-scripts`.** `patch-package` runs as a
`postinstall` script. In environments that disable lifecycle scripts —
increasingly common in hardened CI and after recent supply-chain
incidents like the [`Shai-Hulud` worm (Sept/Nov
2025)](https://www.reversinglabs.com/blog/shai-hulud-worm-npm) —
declared patches simply do not apply, with no error and no warning.
Production code can be installed missing fixes that are committed in the
project.
- **Broken with workspaces**
([ds300/patch-package#277](ds300/patch-package#277)).
- **Broken with `install-strategy=linked`**
([ds300/patch-package#595](ds300/patch-package#595)).
- **Unmaintained.**
The headline outcome: reproducible, source-controlled dependency
hotfixes that survive `--ignore-scripts` and work across every npm
install strategy and across workspaces.
## Relationship to #94
This RFC is a direct response to
[#94](#94) (closed in 2020 as a
footgun). The 2020 proposal was an ad-hoc `npm install --patch
foo.patch` flag with no manifest record, no lockfile linkage, no
transitive-dep support, and no failure-mode story; @isaacs's footgun
objection was correct for that shape. This RFC is structured the
opposite way — explicit manifest, lockfile-hashed, fail-loud-by-default,
version-gated, publish-isolated. A row-by-row response is in the RFC's
_Prior Art → npm/rfcs#94_ section.
See the RFC for the full design, alternatives considered, implementation
plan, tests, and unresolved questions.
---
> **Disclosure**: [Claude Code](https://claude.com/claude-code) was used
to draft this PR description and the initial version of this RFC and to
iterate on it during review.1 parent bcf162f commit 5dd695c
1 file changed
Lines changed: 546 additions & 0 deletions
0 commit comments