Skip to content

chore: upgrade to NPM v12 - #24

Merged
coderbyheart merged 1 commit into
mainfrom
npm-v12
Aug 5, 2026
Merged

chore: upgrade to NPM v12#24
coderbyheart merged 1 commit into
mainfrom
npm-v12

Conversation

@coderbyheart

@coderbyheart coderbyheart commented Aug 5, 2026

Copy link
Copy Markdown
Member

Require npm >=12.0.2 <13 for this project. The Node.js requirement is left unchanged. It is enforced via
check-node-version on npm install and npm ci.

Why

npm v12 turns three code-execution paths off by default — most notably the
unauthorized execution of install scripts, which is the primary vector for
supply-chain attacks via compromised dependencies
(GitHub changelog):

  • allowScripts now defaults to off, so npm install no longer executes
    preinstall, install or postinstall scripts from dependencies unless they
    are explicitly allowed in package.json. This also covers prepare scripts
    from git, file and link dependencies.
  • --allow-git now defaults to none, which closes a code-execution path
    where a git dependency's .npmrc could override the git executable, even with
    --ignore-scripts.
  • --allow-remote now defaults to none, blocking dependencies from remote
    URLs such as HTTPS tarballs.

Pinning engines.npm to >=12.0.2 <13 and failing the install when it is not
met means these protections cannot be silently bypassed by running an older npm
locally or in CI.

How

  • engines.npm is set to >=12.0.2 <13. engines.node is left untouched.
  • check-node-version --package runs from the prepare script, which npm
    executes on npm install and npm ci.
  • CI installs the npm version declared in engines.npm through the new
    .github/actions/install-npm composite action, added after each
    actions/setup-node step.

The check is skipped during npm publish and npm pack, because semantic-release bundles its own npm (@semantic-release/npm depends on npm@^11.6.2) and runs the publish with that version rather than the one installed in CI.

Require npm >=12.0.2 <13, enforced via check-node-version on npm install and
npm ci. CI installs the version from engines.npm via the new
.github/actions/install-npm composite action.

The motivation is that npm v12 turns three code-execution paths off by
default, most notably the unauthorized execution of install scripts:

- allowScripts now defaults to off, so npm install no longer executes
  preinstall, install or postinstall scripts from dependencies unless they
  are explicitly allowed in package.json. This also covers prepare scripts
  from git, file and link dependencies.
- --allow-git now defaults to none, which closes a code-execution path where
  a git dependency's .npmrc could override the git executable, even with
  --ignore-scripts.
- --allow-remote now defaults to none, blocking dependencies from remote
  URLs such as HTTPS tarballs.

See
https://github.blog/changelog/2026-06-09-upcoming-breaking-changes-for-npm-v12/

The check is skipped during npm publish and npm pack, because
semantic-release bundles its own npm (@semantic-release/npm depends on
npm@^11.6.2) and runs the publish with that version rather than the one
installed in CI.

The Node.js requirement is left unchanged.
@coderbyheart
coderbyheart requested a review from a team as a code owner August 5, 2026 09:41

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 7ab1f8f. Configure here.

Comment thread package.json
"scripts": {
"test": "node --no-warnings --experimental-transform-types --test \"./*.spec.ts\""
"test": "node --no-warnings --experimental-transform-types --test \"./*.spec.ts\"",
"prepare": "case \"$npm_command\" in install|ci) check-node-version --package ;; esac"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prepare script breaks Windows

Medium Severity

The new prepare script uses POSIX case/esac syntax. On Windows, npm runs lifecycle scripts with cmd.exe by default, which does not understand that syntax, so npm install and npm ci fail when prepare runs.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 7ab1f8f. Configure here.

@coderbyheart

Copy link
Copy Markdown
Member Author

Security fix, no review required.

@coderbyheart
coderbyheart merged commit 16a1674 into main Aug 5, 2026
2 checks passed
@coderbyheart
coderbyheart deleted the npm-v12 branch August 5, 2026 11:48
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.

1 participant