Article

📦 npm ciとnpm installの違い:CIで依存関係を再現可能にする

npm, nodejs, githubactions, ci

Node.jsのCIでは、依存関係のインストールにnpm installではなくnpm ciを使うことがよくあります。

npm installは依存関係の追加・更新に向いており、package.jsonとpackage-lock.jsonが一致しない場合はlockfileを更新することがあります。一方、npm ciは既存のpackage-lock.jsonを変更せず、両者が一致しなければエラーにします。

使い分け

場面 コマンド
パッケージを追加する npm install <package>
依存関係を更新する npm install
CIで再現可能なインストールを行う npm ci

package-lock.jsonは何のためにあるか

package.jsonは必要なパッケージと許容するバージョン範囲を宣言します。

{
  "dependencies": {
    "express": "^5.1.0"
  }
}

一方、package-lock.jsonは実際に解決された依存関係のツリーを記録します。

npm公式ドキュメントでは、開発者・デプロイ・CIで同じ依存ツリーを再現する用途が明記されています。そのため、アプリケーションでは通常package-lock.jsonをGitへコミットします。

npm ciの特徴

現在のnpm公式ドキュメントでは、npm ciには次の特徴があります。

  • package-lock.jsonが必要
  • package.jsonとlockfileが一致しなければ失敗する
  • package.jsonやpackage-lock.jsonを書き換えない
  • 個別パッケージの追加には使えない
  • 既存のnode_modulesがあれば削除してからインストールする

この「不一致なら失敗する」という性質がCIでは重要です。

例えばpackage.jsonだけを変更し、lockfileを更新し忘れた場合、npm ciならそのミスをCIで検出できます。

GitHub Actionsで使う

name: CI

on:
  pull_request:
  push:
    branches: [main]

permissions:
  contents: read

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-node@v7
        with:
          node-version: 24
          cache: npm
      - run: npm ci
      - run: npm test
      - run: npm run build

actions/setup-nodeの公式READMEでも、npmキャッシュとnpm ciを組み合わせる例が掲載されています。

cache: npmはnpmが取得したパッケージデータをキャッシュする設定で、node_modulesそのものをキャッシュするわけではありません。

npm ciだけでは環境全体は固定されない

lockfileを固定しても、次の差は別途管理が必要です。

  • Node.jsのバージョン
  • npmのバージョン
  • OS
  • CPUアーキテクチャ
  • 環境変数

特にNode.jsのバージョンは、CIとローカルで揃えるのがおすすめです。

よくあるハマりどころ

package-lock.jsonをコミットしていない

lockfileがなければnpm ciは使えません。アプリケーションでは通常、package-lock.jsonをGit管理します。

npm ciの前にnpm installしている

次の2行を連続して実行する必要は基本的にありません。

npm install
npm ci

CIではnpm ciだけで依存関係をインストールできます。

npm ciが失敗したのでnpm installへ戻す

lockfile不整合で失敗した場合は、CIを緩めるのではなくローカルで依存関係を更新します。

npm install
git diff -- package.json package-lock.json

git diffはGit管理中の変更差分を確認するコマンドです。ここでは依存関係の2ファイルだけを対象にしています。

実務での運用

  1. 依存追加・更新はnpm install
  2. package.jsonとpackage-lock.jsonを一緒にコミット
  3. CIはnpm ci
  4. Node.jsのバージョンもCIとローカルで揃える

npm installとnpm ciはどちらか一方を選ぶものではなく、開発時とCIで役割を分けて使うコマンドです。

参考