Skip to content

Deny unneeded esbuild/fsevents install scripts in every v2 install, and guard against unreviewed ones #2712

Closed

Description

@cliffhall

Problem

npm 11.19 gates dependency install scripts behind an allowScripts policy (RFC npm/rfcs#868). In 11.x a package that is unreviewed (neither allowed nor denied) still runs its script with only a warning. Only an explicit false blocks it (@npmcli/arborist/lib/arborist/rebuild.js: isScriptAllowed(...) === false).

v1 denied the two packages that have scripts in #2077. v2 never got the same change, so every v2 install runs them today. npm install-scripts ls on v2/main:

Install Unreviewed install scripts
root fsevents@2.3.3
clients/web esbuild@0.28.2, fsevents@2.3.2, fsevents@2.3.3
clients/cli, clients/mcpdo, clients/tui esbuild@0.28.2, fsevents@2.3.3
clients/launcher none

Neither script is needed, for the reasons #2077 gives. esbuild gets its platform binary through optionalDependencies (@esbuild/<platform>), so its install.js only validates it or downloads a fallback. fsevents ships a prebuilt fsevents.node, and its install script is only a node-gyp rebuild fallback.

Proposed change

  1. Deny by bare name in each install that has a script. v2 is not a workspace, and npm reads allowScripts only from the package.json of the install it is running in, so each install needs its own entry:

    • root: "allowScripts": { "fsevents": false }
    • web, cli, mcpdo, tui: "allowScripts": { "esbuild": false, "fsevents": false }

    Deny rather than approve-and-pin. A deny by bare name blocks every version, so the version not being pinned does not matter. Approving would mean exact-version pins and dependency churn for scripts we don't want.

  2. Add a verify:install-scripts guard in validate:guards. It runs npm install-scripts ls --json in all six installs and fails on any unreviewed entry. Until npm makes blocking the default, this is the only thing that stops a new dependency's install script from running silently. With the guard, each new script becomes a deliberate approve-or-deny decision in review.

Do not use ignore-scripts. It would also disable the root postinstall (scripts/install-clients.mjs) that installs every client.

Verification

Related

Activity

  1. added this to the v2.12.0 milestone on Oct 13, 2026
  2. added
    v2Issues and PRs for v2
    choreMaintenance: deps, build tooling, CI, cleanup — no user-facing behavior change
    on Oct 13, 2026
  3. modified the milestones: v2.12.0, v2.11.0 on Oct 13, 2026
  4. self-assigned this
    on Oct 13, 2026
  5. cliffhall commented on Oct 13, 2026

    @cliffhall
    MemberAuthor

    Shipped in #2714 (merge 15d7721). CI's npm 10 still runs the denied scripts; that follow-up is #2715.

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

Metadata

Metadata

Assignees

Labels

choreMaintenance: deps, build tooling, CI, cleanup — no user-facing behavior changev2Issues and PRs for v2

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions