npm install と npm ci の違い

Node.js のプロジェクトを触っていると、ほぼ無意識に叩いているコマンドがあります。

npm install

一方で、CI や README には、こんなコマンドも書かれている。

npm ci

正直なところ、「どっちも依存関係を入れるコマンドでしょ?」くらいの理解で使っている人も多いと思います。

私自身も、最初はそうでした。

ただ、Node.js の管理や CI 運用を整理していく中で、この2つは用途がまったく違うコマンドだと分かってきました。


結論:役割が違う

まず結論です。

  • npm install → 依存関係を「調整・更新」するためのコマンド
  • npm ci → 依存関係を「完全に再現」するためのコマンド

同じ「インストール」に見えて、目的がまったく違います。


npm install は「開発用」

npm install は、開発中に依存関係を変更するためのコマンドです。

特徴を整理すると、

  • package.json をもとに依存関係を解決する
  • package-lock.json があれば参考にする
  • 必要に応じて lockfile を更新する
  • 既存の node_modules を使い回す

つまり、

依存関係を追加・更新するためのコマンド

なお、npm install は lockfile を尊重しますが、package.jsonpackage-lock.json の内容が一致していない場合、lockfile を更新して整合を取ります。たとえば package.json の依存バージョンだけを変更した状態で実行すると、対応する依存解決結果が package-lock.json に反映されます。

という位置づけです。


npm ci は「再現用」

一方、npm ci はまったく性格が違います。

  • package-lock.json必須
  • package.json と lockfile がズレていたら 即エラー
  • node_modules一度削除してから入れ直す
  • lockfile は一切変更しない

このため、package.jsonpackage-lock.json が一致していない状態では npm ci はエラーで停止します。実務では、依存関係を変更したときはまず npm install で lockfile を更新し、その後の通常作業や CI では npm ci を使う、という役割分担にしておくと混乱を防げます。


まとめ

  • npm install依存関係を変更するためのコマンド
  • npm ci環境を正確に再現するためのコマンド

実務では、

変更するときだけ install、それ以外は ci

このルールだけ覚えておけば十分です。