
pnpmが「速い」「軽い」「戻れない」と言われる理由は、設定やコマンドではなく node_modules の構造そのもの にあります。npm や yarn と同じ JavaScript パッケージマネージャーでありながら、pnpm は依存関係の扱い方を根本から見直しました。本記事では、pnpm の node_modules が何をどう変えたのかを、内部構造と設計思想の観点から解説します。表面的な比較ではなく、「なぜこの仕組みなのか」を理解することで、pnpm を使うべき理由が見えてきます。
目次
目次
従来の node_modules はなぜ問題だったのか
npm や yarn が採用してきた従来の node_modules は、「とにかく動く」ことを最優先に設計されてきました。その結果、多くの問題を抱えることになります。
代表的なのが 依存関係のフラット化 です。あるパッケージが内部的に依存している別のパッケージが、いつの間にか自分のプロジェクトから直接参照できてしまう。これは一見便利ですが、依存関係の境界を曖昧にします。
さらに問題なのが、以下の点です。
- 同じパッケージがプロジェクトごとに何度もインストールされる
- node_modules が巨大化し、ディスクを圧迫する
- 「なぜ動いているのか分からない依存関係」が生まれる
結果として、壊れやすく、再現性の低い環境が出来上がります。

pnpm の node_modules はどう違うのか(全体像)
pnpm はこの問題を「運用」ではなく「構造」で解決しようとしました。
pnpm の最大の特徴は、実体のパッケージを node_modules 直下に置かないことです。代わりに、.pnpm ディレクトリにすべての実体を集約し、必要な場所にリンクを張ります。
pnpm の node_modules は、次のような二層構造になっています。
.pnpm:実体(パッケージ本体)が格納される場所node_modules/パッケージ名:リンクのみが存在する場所
見た目は従来と似ていますが、中身はまったく別物です。

ハードリンクとシンボリックリンクの仕組み
pnpm がディスク容量を大幅に削減できる理由は、リンクの使い分けにあります。
.pnpm内の実体:ハードリンク- 各プロジェクトの node_modules:シンボリックリンク
これにより、同じバージョンのパッケージは 1度だけダウンロード され、複数のプロジェクトで共有されます。
重要なのは、これは pnpm 独自の仕組みではなく、OS レベルのファイルシステム機能を活用している点です。ファイルシステムが同一であれば、複数のプロジェクトが同じ実体を安全に参照できます。
その結果、次のようなメリットが生まれます。
- インストールが高速
- ディスク使用量が少ない
- キャッシュが自然に効く

なぜ pnpm は「幽霊依存」を許さないのか
pnpm が「厳しい」と言われる理由のひとつが、依存関係の扱いです。しかしこれは欠点ではなく、意図された設計です。
幽霊依存(Phantom Dependencies)とは、
package.json に書かれていない依存関係を、たまたま参照できてしまう状態
を指します。
npm や yarn ではフラット構造の影響で幽霊依存が起きやすく、pnpm では原則として発生しません。pnpm は「宣言されていない依存関係は存在しないものとして扱う」ことで、依存関係を 明示的かつ健全 に保ちます。
一時的にエラーは増えますが、長期的には壊れにくい構成になります。

pnpm の node_modules 構造を実際に見てみる
pnpm 環境の node_modules は、概念的には次のような構成になります。
- node_modules/
- react(シンボリックリンク)
- lodash(シンボリックリンク)
- .pnpm/
- react@18.x.x/
- lodash@4.x.x/
重要なのは、import / require の書き方は従来と変わらないことです。Node.js のモジュール解決アルゴリズムは、リンクであるかどうかを意識しません。
開発者は構造を知らなくても使えますが、理解しておくとトラブルシュートが圧倒的に楽になります。
pnpm を使うと何が変わるのか(実務視点)
実務で pnpm を使うと、次のような変化を実感します。
- 初回インストール後の速度が非常に速い
- CI のキャッシュサイズが小さくなる
- 複数案件を扱っても環境が壊れにくい
特に monorepo や複数サイト管理では、「依存関係を共有できる」ことの恩恵が大きくなります。
pnpm が向いているケース・向いていないケース
向いているケース
- 複数プロジェクトを並行して管理する
- monorepo 構成を採用している
- CI / Docker を重視する
注意が必要なケース
- 古いツールが node_modules を直参照している
- npm 前提で書かれた独自スクリプトが多い
ただし多くの場合、問題はツール側にあるため、pnpm を機に構成を見直す価値は十分にあります。
npm / yarn から pnpm に移行する際の注意点
移行時に注意すべき点は次の通りです。
- lockfile に互換性がない
- 幽霊依存がエラーとして顕在化する
- CI のキャッシュパスを見直す必要がある
最初は戸惑いますが、直すべき依存関係が見えること自体が大きなメリットになります。
まとめ:pnpmは「速さ」より「健全さ」を選んだ依存管理
pnpm の node_modules は、単なる高速化のための仕組みではありません。依存関係を正しく定義し、壊れにくい環境を作るための設計です。
一度この構造に慣れると、「なぜ今まであんなに壊れやすかったのか」と感じるようになります。pnpm は速いから選ばれているのではなく、正しい依存管理を強制するから信頼されているのです。





