npmはNode.jsに同梱されているJavaScriptのパッケージマネージャです。レジストリからパッケージを取得するCLI、公開されたパッケージを保管するレジストリ、依存を書き留めるpackage.jsonという3つの仕組みを組み合わせた構成です。この記事では、インストールからpackage.jsonの生成までの手順、npm installとnpm ciの使い分け、semverの範囲指定、2026年7月に出たnpm 12の破壊的変更、そしてnpm auditとtrusted publishingによる公開時の守り方までを扱います。バージョンや仕様は2026年9月17日時点の公式ドキュメントとレジストリの実測値に基づいています。
まとめ:npmの役割とv12以降に切り替えるべき運用の結論
npmが担うのは、依存パッケージの取得・記録・再現の3つです。package.jsonが「どの範囲を許すか」を書き、package-lock.jsonが「実際に何が入ったか」を固定します。この2ファイルの役割を取り違えたまま運用すると、手元では動くのにCIだけ落ちる状態になります。
2026年9月17日時点のnpm CLIの最新版は12.0.2で、npmレジストリのlatestタグから確認できます。v12では依存パッケージのライフサイクルスクリプトが既定でブロックされ、allow-gitとallow-remoteの既定値もnoneになりました。既存の手順書をそのまま流すと止まります。
公開側はさらに動いています。classic tokenは2025年12月9日に全て失効し、書き込み権限を持つトークンの有効期限は最長90日です。CI/CDからパッケージを公開しているなら、OIDCを使うtrusted publishingへ移すのが現実的な着地点になります。
npmを構成するCLI・レジストリ・package.jsonの3要素と役割分担
npmという言葉は、コマンド・サービス・設定ファイルのどれを指しているかで意味が変わります。最初にこの3層を分けて捉えると、あとの手順が迷子になりません。
レジストリとCLIとサイトが分担する範囲と公開パッケージが届く流れ
npmの公式ドキュメントでは、npmは3つの構成要素(ウェブサイト・CLI・レジストリ)から成ると説明されています。ウェブサイトはパッケージの検索とアカウント管理、CLIはターミナルからの操作、レジストリはJavaScriptソフトウェアとメタ情報を収めた公開データベースです。
取得から公開までの実際の流れは次のとおりです。開発者がnpm installを叩くと、CLIがレジストリへ問い合わせて圧縮されたtarballを取得し、node_modules配下へ展開します。公開側はnpm publishでtarballをレジストリへ送ります。ブラウザで見るnpmのページは、このレジストリの内容を表示している窓口にすぎません。
dependenciesとdevDependenciesで変わる配布物の境界
package.jsonの仕様では、実行時に必要な依存をdependencies、ビルドやテストにだけ必要な依存をdevDependenciesへ書き分けます。この分離が効くのは本番のインストール時です。npm install --omit=devを使うと、devDependenciesを除いた状態を再現できます。
境界の判断は「本番のプロセスがrequireまたはimportするか」で決めます。ExpressやReactのようにランタイムへ載るものはdependencies、TypeScriptコンパイラやテストランナーはdevDependenciesです。この振り分けを雑にすると、コンテナイメージに不要な数百MBが載ります。
インストールからpackage.json生成までの実行手順と確認コマンド
npmを単体でインストールする場面はほとんどありません。Node.jsを入れれば付いてきます。
Node.js同梱のnpmを確認しnpm initで雛形を作る手順
手元の環境で使えるかどうかは、2つのコマンドで判定できます。Node.jsの導入そのものはNode.jsとは?仕組み・版の選び方・標準機能で動かす手順を実装目線で解説で整理しているため、ここではnpm側の初期化に絞ります。
node -v
npm -v
npm init -y
npm install express
npm ls --depth=0
npm init -yを実行すると、対話なしでpackage.jsonが生成されます。なお、npm 12ではnpm initの既定ライセンスがISCから空文字列に変わりました。社内配布のパッケージでライセンス欄を空のまま公開しないよう、雛形作成の直後にlicenseフィールドを埋める運用にしておきます。
npm 12が要求するNode.jsの版と合わない環境で出る失敗
npm 12.0.2のenginesフィールドは^22.22.2 || ^24.15.0 || >=26.0.0です(レジストリのメタ情報で実測)。Node.js 22系でも22.22.2未満、24系でも24.15.0未満では条件を満たさず、警告やエラーになります。
古いNode.jsを使い続ける案件では、npm 11系の最終版である11.19.1に留める判断も現実的です。npm自体はnpm install -g npm@11のようにメジャー系列を指定して固定できます。CIイメージのNode.js版を上げないままnpmだけ最新へ追従させるのが、最も詰まりやすい組み合わせでした。
npm installとnpm ciの違いとlockfileが壊れる場面の切り分け
この2つを同じものとして扱っているプロジェクトは、CIの再現性を失っています。役割は明確に分かれます。
node_modulesを作り直すnpm ciがCIで前提にする条件
npm ciの公式ドキュメントには4つの決めごとが書かれています。package-lock.jsonが存在しなければ実行できないこと、既存のnode_modulesは開始前に自動削除されること、lockfileとpackage.jsonの内容が食い違えばlockfileを更新せずエラー終了すること、そして個別パッケージを引数に取れないことです。
npm ci
npm ci --omit=dev
裏を返すと、lockfileをリポジトリへコミットしていないプロジェクトではnpm ciが一切使えません。CIのビルド時間を削る前に、まずpackage-lock.jsonをコミットする。ここが出発点になります。
package.jsonだけ手で書き換えたときにCIが落ちる流れ
典型的な事故はこう進みます。エディタでpackage.jsonのバージョン範囲を直接書き換え、ローカルでは既にnode_modulesがあるため動作し、そのままコミットする。CIでnpm ciが走り、lockfileとの不一致でエラー終了します。
直し方は単純で、ローカルでnpm installを実行してlockfileを再生成し、両方のファイルを同じコミットに含めます。レビュー時にpackage.jsonだけが変更されているプルリクエストを弾く運用にしておくと、この型の失敗は起きなくなります。
semverの範囲指定とnpm updateで意図せず上がる依存の抑え方
「昨日まで通っていたビルドが、何も変えていないのに落ちた」の多くは、範囲指定の読み違いから来ます。
キャレットとチルダで許容される更新幅の違いとバージョン固定の使い分け
npmのセマンティックバージョニング解説に沿って、記号ごとの許容範囲を整理します。
| 記述 | 許容される更新 | 使いどころ |
|---|---|---|
| ^1.2.3 | 1.2.3以上2.0.0未満(マイナーとパッチ) | 安定した公開ライブラリの既定 |
| ~1.2.3 | 1.2.3以上1.3.0未満(パッチのみ) | マイナー更新で壊れた実績があるもの |
| 1.2.3 | 更新しない(完全固定) | ビルドツールや破壊的変更が多い依存 |
| ^0.2.3 | 0.2.3以上0.3.0未満 | 0.x系は例外扱いになる点に注意 |
0.x系のキャレットがパッチ相当の幅しか許さない点は、見落とされがちです。メジャー1に達していないパッケージを本番の中核に置くなら、範囲ではなく完全固定にします。
npm outdatedとnpm lsで更新前に影響範囲を数える手順
更新の前に、何が何を引いているのかを数えます。npm outdatedはCurrent(現在)・Wanted(範囲内で上げられる版)・Latest(最新版)の3列を出すため、範囲指定のままでどこまで上がるかが判断できます。
npm outdated
npm ls express
npm ls --depth=0
npm ls パッケージ名を使うと、直接依存なのか、別のパッケージが間接的に引いているのかが木構造で見えます。間接依存であれば、そのパッケージ単体を上げても解決しません。親側の更新か、overridesによる強制が必要になります。
npm 12の破壊的変更とライフサイクルスクリプト既定ブロックの影響
npm 12.0.0は2026年7月8日に公開されました(レジストリのtime情報で実測)。既存プロジェクトに直接ぶつかる変更が複数入っています。
依存のライフサイクルスクリプトが既定で止まる変更と再許可の判断
npm v12.0.0のリリースノートで挙げられている変更のうち、影響が大きいのは依存パッケージのライフサイクルスクリプトが既定でブロックされる点です。インストール時にpostinstallでネイティブモジュールをビルドしていたパッケージは、そのままでは処理が走りません。
この変更は、インストール時のスクリプト実行を踏み台にしたサプライチェーン攻撃への対応です。再許可するかどうかは、対象パッケージを名指しで判断します。全体をまとめて許可に戻す設定は、v12で得られた防御をそのまま捨てる操作になるため採用しません。
allow-gitやadduser削除で動かなくなる既存手順の洗い出し
同じリリースで、allow-gitとallow-remoteの既定値がnoneに変わりました。社内のGitリポジトリを直接依存に書いているプロジェクトは、明示的な許可なしでは取得できません。
npm adduserが削除され、npm loginへ統合されたnpm shrinkwrapとnpm-shrinkwrap.jsonのサポートが削除され、package-lock.jsonへの移行が必要になった- 未知の.npmrc設定値や不明なCLIフラグが、警告ではなくエラーになった
- グローバルインストール時のmanページ登録がなくなり、
npm help installを使う形になった
この4点は、いずれも社内Wikiの手順書やDockerfileに残っている記述を直撃します。v12へ上げる前に、リポジトリ全体をadduserとshrinkwrapで検索しておくと、切り替え当日の停止時間を短くできます。
npm auditとtrusted publishingで固める依存と公開の安全策
依存を取り込む側と、パッケージを公開する側で、守り方は別です。両方を扱います。
npm auditの終了コードとaudit fix –forceを避ける運用
npm auditの公式ドキュメントによると、このコマンドは依存関係の情報をレジストリへ送り、既知の脆弱性レポートを受け取ります。終了コードは脆弱性が無ければ0、見つかれば非ゼロです。--audit-levelで、どの深刻度から非ゼロにするかを指定します。
npm audit --audit-level=high
npm audit fix --dry-run
npm audit --omit=dev
注意したいのはnpm audit fix --forceです。このオプションはsemver-majorのバージョン更新まで許可するため、脆弱性は消えても本番の挙動が変わります。CIのゲートには--audit-level=highを置き、修正の適用は--dry-runで差分を見てから手で判断する。この順番を崩さないようにします。
classic token失効後の公開をOIDCへ移す手順と期限
公開側の前提は2025年から2026年にかけて入れ替わりました。GitHubの公式ディスカッションによれば、classic tokenは2025年12月9日に全て停止し、再作成もできません。npm loginが発行するのは有効期限付きのセッショントークンで、自動化には粒度の細かいgranular access tokenを使います。書き込み権限を持つトークンの有効期限は最長90日です。
trusted publishersは、OIDCによってCI/CDとnpmの間に信頼関係を結び、長期トークンを持たずに公開する仕組みです。対応しているのはGitHub Actions(GitHubホストランナー)、GitLab CI/CD(共有ランナー)、CircleCI(クラウド)の3つで、セルフホストランナーは未対応です。GitHub ActionsまたはGitLab CI/CD経由の公開では、provenance(来歴証明)が自動で付きます。2026年9月3日以降に作成する設定ではnpm stage publishが自動で許可され、npm publishによる直接公開も認めるかどうかを選ぶ形に変わりました。
workspacesによるモノレポ運用とpnpm・yarnへ乗り換える判断基準
複数パッケージを1つのリポジトリで扱う段階になると、npm単体で足りるかどうかの判断が必要になります。
workspacesで1つのlockfileに束ねる構成と向かない規模
npm workspacesは、ルートのpackage.jsonにworkspaces配列を書くことで、配下のパッケージをまとめて扱う仕組みです。lockfileはルートに1つだけ生成され、共通依存は巻き上げられます。
{
"name": "example-monorepo",
"workspaces": ["packages/*"],
"private": true
}
向くのは、フロントエンドとAPIと共通型定義のように、同じリリースサイクルで動く3から5個程度のパッケージ構成です。リリース時期が独立した10個以上のパッケージを1つのlockfileへ束ねると、片方の依存更新がもう片方のCIを巻き込みます。その規模になったら、リポジトリ分割かツール変更のどちらかを検討します。
pnpmやvltへ移す前に測るインストール時間とディスク使用量
乗り換えの判断材料は、感覚ではなく数字です。クリーンインストールにかかる秒数、node_modulesのディスク使用量、CIキャッシュのヒット率。この3つを現行のnpmで測ってから比較します。
候補として、共有ストア方式でディスクを節約するpnpmとは?共有ストアの仕組みとv12のRust実装・モノレポ運用を解説、npm互換をうたうvltとは?npm互換パッケージマネージャの1.0到達点と移行判断を実装者向けに解説があります。チーム全員の手元でツール版を揃える手段としては、corepackでpnpmを管理する方法|corepack enable・prepareの使い方とNode.js 25の変更【2026年】で扱っているCorepackが使えます。
受託開発でnpmを使い続ける条件と他ツールへ移すべき案件の線引き
ここは判断を明示します。パッケージマネージャの変更は、機能を1つも増やさないまま数日を使う作業だからです。
npmのまま進めてよい案件の条件と乗り換えを見送るべき具体的な場面
npmのままで問題ないのは、単一アプリケーション構成で、直接依存が50個前後、CIのインストールが2分以内に収まっている案件です。この条件ではpnpmへ移しても短縮幅は数十秒で、移行とCI再設定の工数を回収できません。lockfile形式が変わることでレビュー時の差分が読めなくなる副作用もあります。
逆に、workspacesで10個以上のパッケージを抱え、CIのインストールが5分を超え、開発機のディスクをnode_modulesが圧迫しているなら、移行を勧めます。判断の分かれ目は依存の数ではなく、CIの待ち時間が開発の速度に効いているかどうかです。
納品後に効いてくるのは、どのツールを選んだかよりも依存を更新し続ける体制があるかどうかでした。脆弱性の通知を受けて誰がいつ上げるのかが決まっていない場合、保守運用 / 内製化支援のように、更新の判断と作業を継続的に引き受ける体制と組み合わせる方法もあります。
よくある質問
npmの導入と運用でつまずきやすい点を5つ挙げます。
npmとNode.jsはどちらを先にインストールすればよいですか?
Node.jsを入れればnpmも同時に入るため、npmを単体でインストールする必要はありません。導入後にnode -vとnpm -vの両方が表示されれば準備完了です。npmだけを新しくしたい場合はnpm install -g npm@12のようにメジャー系列を指定します。ただしnpm 12.0.2はNode.js 22.22.2以上、24.15.0以上、または26以上を要求するため、Node.js側の版を先に確認してください。
npm installとnpm ciはどう使い分ければよいですか?
開発中の追加や更新にはnpm install、CIや本番ビルドにはnpm ciを使います。npm ciはpackage-lock.jsonを必須とし、既存のnode_modulesを削除してからlockfileどおりに入れ直すため、同じ結果を何度でも再現できる仕組みです。package.jsonとlockfileが食い違う場合はlockfileを更新せずエラー終了するので、CIで不整合を検出する役割も果たします。
package-lock.jsonはGitで管理すべきですか?
アプリケーション開発では必ずコミットします。コミットしていないとnpm ciが実行できず、環境ごとに入る版が変わります。一方、ライブラリとして公開するパッケージでは、利用側の依存解決に委ねるためlockfileを配布物へ含めません。npm 12ではnpm-shrinkwrap.jsonのサポートが削除されたため、固定にはpackage-lock.jsonを使います。
npm audit fixで脆弱性が消えない場合はどうしますか?
間接依存の親パッケージが古い版を掴んでいる場合、npm audit fixでは解消しません。npm ls パッケージ名で誰が引いているかを特定し、親側の更新を待つか、package.jsonのoverridesで版を強制します。--forceはsemver-majorの更新まで許可して挙動を変えるため、本番稼働中のプロジェクトでは--dry-runで差分を確認してから手で対応する方が安全です。
npmからpnpmへ移行するときに何を確認すればよいですか?
先に現行のクリーンインストール時間、node_modulesのディスク使用量、CIキャッシュのヒット率を測ります。そのうえでlockfileを作り直し、postinstallに依存するパッケージとネイティブモジュールが動くかを検証してください。pnpmは既定でnode_modulesの構造が異なるため、依存宣言の漏れがあるパッケージは移行時に露見します。CIの待ち時間が短い案件では、移行そのものを見送る判断も妥当です。
関連記事
- Node.jsとは?仕組み・版の選び方・標準機能で動かす手順を実装目線で解説:npmの土台となるランタイムの版選定と実行モデルを扱っています
- pnpmとは?共有ストアの仕組みとv12のRust実装・モノレポ運用を解説:npmから乗り換える際の第一候補となるツールの仕組みを比較できます
- corepackでpnpmを管理する方法|corepack enable・prepareの使い方とNode.js 25の変更【2026年】:チーム内でパッケージマネージャの版を揃える手段を解説しています
- vltとは?npm互換パッケージマネージャの1.0到達点と移行判断を実装者向けに解説:npm互換を掲げる新しいツールの到達点と移行判断をまとめています