図解で理解する npm の仕組み

図解で理解する npm の仕組み

2025.12.15

製造ビジネステクノロジー部の小林です。

先日、npm へのサプライチェーン攻撃が大きな話題になりましたね。攻撃者が npm パッケージにマルウェアを仕込み、多くのプロジェクトに影響を与える可能性があるという事例が報告されました。
https://zenn.dev/hand_dot/articles/04542a91bc432e

この事件をきっかけに、普段何気なく使っている npm について改めて調べてみることにしました。文章だけで説明するよりも図解の方が理解しやすいと思い、生成AI画像ツール(Google Nano Banana)を使用して npm の仕組みを図解化してみました。

目次

  1. npm とは
  2. package.json と package-lock.json の違い
  3. npm install の内部動作
  4. pnpm と npm の違い
  5. まとめ

npm とは

npm(Node Package Manager)は、Node.jsのパッケージ(ライブラリ)を管理するツールです。誰でも無料で利用でき、世界中の開発者が公開したパッケージを簡単にインストールできます。
unnamed

npm はスマホの App Store と似ています。開発者は必要なパッケージを npm レジストリから簡単にダウンロードして利用できます。

なぜnpmが必要なのか?

npmがない場合

  • ライブラリの公式サイトを探す
  • ファイルをダウンロード
  • 手動でプロジェクトに配置
  • バージョン管理も自分で行う

npmがある場合
npm install <パッケージ名>
これだけで完了!依存関係も自動で解決してくれます。

実際に使ってみる

例えば、人気のWebフレームワーク「Express」をインストールする場合をみてみます。

まず、新しいプロジェクトを初期化します。

# プロジェクト初期化
pnpm init

スクリーンショット 2025-12-14 23.49.40

次に、Express をインストールします。

# Expressをインストール
pnpm install express

スクリーンショット 2025-12-14 23.52.31
これだけで、Expressとその依存関係が全て自動的にインストールされます。

インストール後、以下のファイルとフォルダが作成されます。

  • package.json - Express が依存関係として記録される
  • pnpm-lock.yaml - インストールした正確なバージョンが記録される(npm の場合は package-lock.json)
  • node_modules/ - Express と依存パッケージが保存される

7

package.json と package-lock.json の違い

npm install を実行すると、package.json と package-lock.json という2つのファイルが作成・更新されます。名前は似ていますが、役割は全く異なります。
4

package.jsonは「何が必要か」を定義するファイルです。開発者が手動で編集する設計書のようなものです。

package-lock.jsonは「実際に何をインストールしたか」を記録するファイルです。npm が自動生成し、直接編集しないファイルです。

バージョン指定の意味

^(キャレット)は「メジャーバージョンは固定、マイナー・パッチは更新OK」という意味です。
3

例えば ^1.2.3 の場合

  • 1.2.4 にアップデート可能(パッチバージョン)
  • 1.3.0 にアップデート可能(マイナーバージョン)
  • 2.0.0 にはアップデートしない(メジャーバージョン)

なぜ両方必要なのか?

1
package-lock.json がないと、チームメンバーや異なる時期に同じプロジェクトをセットアップしたときに、異なるバージョンがインストールされる可能性があります。これは「私の環境では動くのに…」という問題の原因になります。

npm install の内部動作

npm installコマンドを実行すると、裏側で何が起こっているのでしょうか?
5

  1. package.jsonを読む
    npmはまずpackage.jsonを読み、必要なパッケージのリストを確認します。
  2. npmレジストリに問い合わせ
    https://registry.npmjs.org にアクセスして、各パッケージの最新バージョンを確認します。
  3. 依存関係を解決
    パッケージが依存している他のパッケージも全て確認します。1つのパッケージが50個以上の依存関係を持つこともあります。
  4. ダウンロード
    パッケージとその依存関係を全てダウンロードします。
  5. node_modules/に保存
    ダウンロードしたファイルをnode_modules/フォルダに展開します。
  6. package-lock.jsonを作成/更新
    インストールしたパッケージの正確なバージョン番号、ダウンロード元URL、整合性チェック用ハッシュ値を記録します。

pnpm と npm の違い

pnpm(Performant npm)は、npmの改良版として2017年に登場したパッケージマネージャーです。
最大の違いはファイル保存方式です。

npm(コピー方式)

  • 各プロジェクトに全てのパッケージをコピーして保存
  • 同じパッケージでも、プロジェクトごとに重複してダウンロード
  • ディスク容量を大量に消費

pnpm(シンボリックリンク方式)

  • 全てのパッケージを ~/.pnpm-store/ という1箇所に保存
  • 各プロジェクトからはシンボリックリンクで参照
  • 同じパッケージは一度だけダウンロード
  • ディスク容量を大幅に節約

おわりに

今回、npm の仕組みを深掘りしてみて、普段何気なく使っているツールの裏側で多くの処理が行われていることを実感しました。
なんとなく使っていたコマンドも、裏側の仕組みを知ると「なぜエラーが出たのか」「なぜlockファイルが必要なのか」が見えてきますね。

図解にすることで、npm の仕組みが整理できました。Nano Banana、便利ですね!

この記事をシェアする

FacebookHatena blogX

関連記事