RFC: Native Dependency Patching#862
Conversation
|
Hey @manzoorwanijk, There are a few questions I have:
|
|
Thanks @james-pre - three good questions. 1. Multiple patches for the same package. Punted in v1: see Unresolved Questions and Bikeshedding item 6 ("Stacking patches"). The RFC matches at most one patch per resolved node, and stacking is left as an additive extension (selector value becomes an array). The reason for deferring is that with Practical workaround for now: merge the two diffs into a single 2. Patches needed by dependants / transitive consumers. This is intentionally not supported, and the constraint is by design rather than oversight. From the RFC:
So in your example, if The right tool for "I want consumers of 3. Why not consolidate under Fair point - the current mix ( I'd propose:
Happy to update the RFC to use this shape if there's broader agreement. |
Summary
Adds first-class, install-time patching of installed dependencies to the npm CLI, on parity with
pnpm patch,yarn patch, andbun patch. Introducesnpm patch/npm patch ls/npm patch-commit/npm patch-remove, apatchedDependenciesfield inpackage.json, and apatched.{path,integrity}record inpackage-lock.json(lockfileVersion: 4). Patches apply during Arborist's reify step, uniformly across every supportedinstall-strategy(hoisted,nested,shallow,linked).Why now
The third-party
patch-packageis currently the only path to dependency patching for npm users, and it is structurally limited:--ignore-scripts.patch-packageruns as apostinstallscript. In environments that disable lifecycle scripts — increasingly common in hardened CI and after recent supply-chain incidents like theShai-Huludworm (Sept/Nov 2025) — 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.install-strategy=linked(ds300/patch-package#595).The headline outcome: reproducible, source-controlled dependency hotfixes that survive
--ignore-scriptsand work across every npm install strategy and across workspaces.Relationship to #94
This RFC is a direct response to #94 (closed in 2020 as a footgun). The 2020 proposal was an ad-hoc
npm install --patch foo.patchflag 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 → #94 section.See the RFC for the full design, alternatives considered, implementation plan, tests, and unresolved questions.