はじめに
対象読者は、npm install を日常的に使う Node.js 開発者と、CI で依存をインストールしている人です。npm のメジャーアップデートで何が変わるか知りたい方に向けて書いています。
npm 12 は、依存パッケージのライフサイクルスクリプト(postinstall など)を既定でブロックします。これまで暗黙に動いていたネイティブビルドや、git 経由の依存が、アップグレード後に「何も言わずに動かない」あるいは「エラーで止まる」状態になりえます。
npm 10.9.9 と npm 12.2.2 を同じ環境で並べて動かし、挙動の差を確かめました。公式のリリースノート(v12.0.0、2026-07-08 公開)に書かれた Breaking changes のうち、インストール系の 4 点を実機で再現します。
この記事で分かること
- npm 10 と npm 12 で、依存の
postinstallの扱いがどう変わるか -
npm install-scripts ls/approveで許可を記録する手順と、package.jsonに書き込まれる内容 -
--strict-allow-scriptsで CI を落とす方法 - git 依存が
EALLOWGITで拒否される挙動 -
min-release-ageの単位と使いどころ
前提条件
- Node.js 22.22.2 以上(npm 12 の要件は
^22.22.2 || ^24.15.0 || >=26.0.0) - 以下は 2026-11-09 JST に、npm 10.9.9(Node v22.23.4 同梱版)と npm 12.2.2(
npm i --prefixで別ディレクトリに導入)を使って確認したものです。npm 12.2.2 の公開日は 2026-11-04(UTC)です
TL;DR
- npm 12 は、依存の
postinstallなどを既定で実行しません。実行したいものはルートのpackage.jsonのallowScriptsに書きます - 許可の記録は
npm install-scripts approve <pkg>がpackage.jsonへ書き込みます。一覧はnpm install-scripts lsです - 未承認のスクリプトがあるとき、通常は警告で続行します。
--strict-allow-scriptsを付けるとESTRICTALLOWSCRIPTSで失敗するので、CI ではこちらが向きます -
allow-gitとallow-remoteの既定はnoneです。github:user/repoのような git 依存はEALLOWGITで拒否されます -
min-release-ageは日数で指定します。公開から日の浅い版を避けるサプライチェーン対策に使えます
npm 12 のインストール時の流れ
実機で確認した範囲を図にすると、依存の install script と git 依存は次のように振り分けられます。
検証環境の作り方
既存の npm 10 を残したまま npm 12 を試すには、作業ディレクトリに npm 自体をインストールします。
npm -v # 10.9.9
npm i --prefix . npm@12.2.2 --no-audit --no-fund
./node_modules/.bin/npm -v # 12.2.2
以降、npm は 10.9.9、./node_modules/.bin/npm は 12.2.2 として扱います。検証用に、postinstall で POSTINSTALL_RAN というファイルを作るだけの最小パッケージ hello-post を用意しました。
{
"name": "hello-post",
"version": "1.0.0",
"scripts": {
"postinstall": "node -e \"require('fs').writeFileSync('POSTINSTALL_RAN','yes')\""
}
}
npm pack で tarball にして、別のプロジェクトからローカル tarball として入れます。
検証 1: postinstall が既定で止まる
同じ tarball を npm 10 と npm 12 で入れた結果です。
== npm 10.9.9
added 1 package in 261ms
POSTINSTALL_RAN
package.json
== npm 12.2.2
added 1 package in 447ms
npm warn install-scripts 1 package had install scripts blocked because they are not covered by allowScripts:
npm warn install-scripts hello-post@1.0.0 (postinstall: node -e "...")
npm warn install-scripts
npm warn install-scripts Run `npm install-scripts ls` to review, or `npm install-scripts approve <pkg>` to allow.
package.json
node_modules/hello-post/ の中身を ls した結果が、npm 10 では POSTINSTALL_RAN を含み、npm 12 では含みません。npm 12 は警告を 1 ブロック出しますが、終了コードは 0 のまま続行します。ログを読まない CI では、気づかないまま通ります。
検証 2: allowScripts で許可を記録する
npm install-scripts ls でブロックされたスクリプトを確認し、approve で許可します。
$ npm install-scripts ls
1 package has install scripts blocked because they are not covered by allowScripts:
hello-post@1.0.0 (postinstall: node -e "...")
Run `npm install-scripts approve <pkg>` to allow, or `npm install-scripts deny <pkg>` to deny.
$ npm install-scripts approve hello-post
Approved file:.../pkg/hello-post-1.0.0.tgz:
added file:.../pkg/hello-post-1.0.0.tgz
この後の package.json は次のようになりました。
{
"name": "consumer",
"version": "1.0.0",
"dependencies": {
"hello-post": "file:../pkg/hello-post-1.0.0.tgz"
},
"allowScripts": {
"file:.../pkg/hello-post-1.0.0.tgz": true
}
}
node_modules を消して入れ直すと、POSTINSTALL_RAN が作られました。許可は package.json に残るので、チームで共有できます。
注意点が 1 つあります。今回はローカル tarball だったため、キーが file:... という解決先になりました。通常のレジストリ依存では pkg@version の形で記録されます(--no-allow-scripts-pin を付けると固定しない書き方になります。ヘルプの記載に基づき、レジストリ依存での書き込み内容は手元では確認していません)。
検証 3: CI では --strict-allow-scripts
承認前の状態で --strict-allow-scripts を付けると、警告ではなくエラーで失敗します。
npm error code ESTRICTALLOWSCRIPTS
npm error --strict-allow-scripts: 1 package(s) have install scripts not covered by allowScripts:
npm error hello-post@1.0.0 (postinstall: node -e "...")
npm error Approve them with `npm install-scripts approve`, deny them with `npm install-scripts deny`, or bypass this check with `--dangerously-allow-all-scripts`.
このとき node_modules は作られませんでした。「新しい依存が勝手に install script を持ち込んだら CI を落とす」運用なら、.npmrc に strict-allow-scripts=true を入れておく方法が使えます(設定名は npm config ls -l の一覧で確認しました。.npmrc 経由の動作自体は未検証です)。
逆に、従来どおり全部実行させたい場合の逃げ道が --dangerously-allow-all-scripts です。名前のとおり、サプライチェーン対策を捨てる設定なので、一時的な移行措置にとどめるのが安全です。
検証 4: git 依存は EALLOWGIT
github:isaacs/ms.js を入れようとした結果です。
npm error code EALLOWGIT
npm error Fetching packages of type "git" have been disabled
npm error Refusing to fetch "github:isaacs/ms.js"
allow-git の既定が "none" なので、git 依存はそもそも取得されません。必要なら allow-git=root(ルートが直接宣言した依存のみ)や all を設定します。allow-remote も同様に既定 none で、ユーザーが指定した tarball URL の依存が対象です。リリースノートによれば、設定値は all または root で緩められます。
検証 5: min-release-age は日数
npm 12 には min-release-age が追加されています。ドキュメントには、指定した日数より前に公開された版だけを使うツリーを組み、該当する版がなければエラーにする、と書かれています。単位が日数であることを実機で確かめました。
$ npm i npm@12.2.2 --min-release-age=3650
npm error code ETARGET
npm error notarget No matching version found for npm@12.2.2 with a date before 11/11/2016, 4:15:53 PM.
$ npm i npm --min-release-age=2000
added 1 package in 2s
# package.json に "npm": "^7.13.0" が入った
3650 を指定すると「10 年前より古い版」を探しに行き、2026-11-04 公開の 12.2.2 は対象外になります。2000 日なら当時の版(7.13.0)が選ばれました。このように、数字の大きさがそのまま「何日待つか」になります。
公開直後の悪意ある版を避けたいなら、7 日程度を指定する使い方が現実的です。ただし、セキュリティ修正を含む版が公開直後に出たときは、その修正も入りません。npm audit fix が止まるケースについて、ドキュメントには「脆弱な版を残して警告し、非ゼロで終了する」という記載があります(動作は手元では未確認です)。
npm 12 のその他の変更(リリースノートの記載)
手元では確認していませんが、v12.0.0 のリリースノートには次の項目も載っています。
- ルートの
preinstallが、依存のインストールより前に実行される -
npm shrinkwrapコマンドとnpm-shrinkwrap.jsonの読み込みが削除された(ロックファイルはpackage-lock.jsonを使う) -
npm adduser、star、stars、unstarが削除された -
npm view --jsonが常に配列を返す - 未知の CLI フラグは警告ではなくエラーになる(未知の
.npmrc設定は警告のまま。新しいstrict-npmrcでエラー化できる) -
npm initの既定ライセンスがISCから空文字になった
npm config ls -l の差分では、init-license が "ISC" から "" に変わっていることを確認できました。progress の既定も、この環境(非 TTY)では true から false になっていましたが、環境依存の可能性があり、リリースノートにも記載はありません。
移行チェックリスト
- Node.js が 22.22.2 以上か確認します
- 現在のプロジェクトで npm 12 を試し、
npm install-scripts lsで止まるパッケージを洗い出します - 必要なものだけ
npm install-scripts approve <pkg>で許可します。--allは避けます - CI に
--strict-allow-scriptsを足し、新しい install script の混入で落ちるようにします - git 依存や URL 依存があれば、
allow-git/allow-remoteの設定が必要かを見直します -
npm-shrinkwrap.jsonを使っている場合はpackage-lock.jsonへリネームします
まとめ
- 実機で確認できたのは、
postinstallの既定ブロック、install-scripts ls/approveとallowScriptsへの記録、--strict-allow-scriptsの失敗、git 依存のEALLOWGIT拒否、min-release-ageが日数であること、の 5 点です - npm 12 の既定ブロックは、警告を出しても終了コード 0 で続行します。「動いているのに必要な処理が走っていない」状態を防ぐには、CI で厳格モードを使います
- 影響が大きいのは、ネイティブビルドや postinstall でバイナリを取得するパッケージと、git 依存を使う構成です
参考
- npm CLI v12.0.0 リリースノート
-
min-release-ageなどの設定の説明は、npm 12.2.2 に同梱されたドキュメント(node_modules/npm/docs/content/using-npm/config.md)で確認しました