Skip to content

fix!: run root preinstall before reify#9267

Open
owlstronaut wants to merge 1 commit intolatestfrom
fix/preinstall-ordering-2660
Open

fix!: run root preinstall before reify#9267
owlstronaut wants to merge 1 commit intolatestfrom
fix/preinstall-ordering-2660

Conversation

@owlstronaut
Copy link
Copy Markdown
Contributor

BREAKING CHANGE: root `preinstall` now runs before dependencies are installed.

Summary

Moves the root preinstall script back to its documented position: before dependencies are installed. Restores behavior that shipped through npm 6 and was unintentionally broken in npm 7 when Arborist took over reify.

Fixes #2660.

The bug

The scripts docs have always said preinstall runs "before the package is installed." Since npm 7, the root package.json's preinstall has actually run after arb.reify() i.e. after every dependency has been resolved, fetched, and unpacked. Arborist explicitly excludes the project root from its rebuild queue (reify.js:1234, !diff.ideal.isProjectRoot), and lib/commands/install.js appended preinstall to the post-reify lifecycle loop along with install, postinstall, prepublish, preprepare, prepare, postprepare. npm ci has the same shape.

Net effect: there is currently no way to run a script at the root before dependencies hit disk. Projects that want to bootstrap auth, generate files consumed during resolution, or gate installs behind a precondition have had no supported hook for five years.

The fix

Split the root lifecycle loop in two:

  1. preinstall runs via a small helper before arb.reify().
  2. install, postinstall, prepublish, preprepare, prepare, postprepare run after reify, as they did before.

Same split applied to npm ci.

Why now, and why not wait for a lifecycle redesign

This has history:

A comprehensive lifecycle redesign is still the right long-term project and has clearly not happened in five years. Gating the revert on it was reasonable in 2021; but has proven that continuing to gate on it in 2026 just means users keep hitting a bug the docs promise doesn't exist. npm 12 is the right window to ship the scoped revert and decouple it from a future lifecycle rewrite.

The code change here is functionally the same as #2713 The differences are: it also patches npm ci, updates the docs to match reality, adds regression tests, and ships in a major (npm 12) rather than being blocked on a design gate that no longer has owners.

Closes / supersedes

When this lands:

BREAKING CHANGE: root \`preinstall\` now runs before dependencies are installed.
@owlstronaut owlstronaut requested a review from a team as a code owner April 21, 2026 21:43
@owlstronaut owlstronaut mentioned this pull request Apr 21, 2026
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Preinstall script runs after installing dependencies

1 participant