
pnpmはZoltan Kochan氏が2017年に公開したNode.js向けのパッケージマネージャで、performant npmの頭文字を取って名付けられました。node_modulesにライブラリを丸ごとコピーする従来の方式と違い、グローバルのコンテンツアドレス可能ストア(CAS)に1つだけ実体を置き、各プロジェクトのnode_modules内からハードリンクで参照する独自方式が最大の特徴です。結果として複数プロジェクトを抱える開発機のディスク使用量を大幅に削減でき、インストール速度もnpm・Yarnと比べて速いケースが多いため、Vue.js・Vite・PreactなどフロントエンドOSSの中核プロジェクトで採用が広がっています。
この記事の目次
- コンテンツストアとハードリンク方式
- 高速インストールと厳格な依存
- モノレポ向けの組込みワークスペース
- npmやYarnとの選び分け
- まとめ
コンテンツストアとハードリンク方式

pnpmは~/.local/share/pnpm/store(macOS/Linux)や%LOCALAPPDATA%\pnpm\store(Windows)に共有ストアを作り、ダウンロードしたパッケージをハッシュ単位で1度だけ保存します。プロジェクトのnode_modules直下にはハードリンクで実体を共有し、依存関係は.pnpmディレクトリの中にシンボリックリンクで階層を再現します。同じバージョンのreactを100プロジェクトで使っていても、ディスク上の実体は1つで済むため、モノレポや個人開発機での効果が顕著です。
ハードリンクは同一ファイルシステム上でしか動作しないため、Dockerボリュームを越えるケースや別ドライブにまたがる場合はオプションで挙動を切り替える必要があります。シンボリックリンクの構造もnpmやYarn 1とは大きく異なり、flatなnode_modulesを前提とした古いツールでは互換性問題が起きることがあります。そうした場合はpnpmのpublic-hoist-patternやnode-linker=hoisted設定で挙動を従来形式に寄せ、漸進的に移行できる逃げ道が用意されています。
高速インストールと厳格な依存

pnpmはpnpm-lock.yamlに全依存の正確な版数とハッシュを記録し、pnpm install --frozen-lockfileで再現性のあるインストールを保証します。ストアにすでに存在するファイルはダウンロードを省略してハードリンクするだけで済むため、2回目以降のインストールが体感で大きく速くなる場面が多くあります。CIではキャッシュキーをpnpm-lock.yamlのハッシュにしておけば、変更がない依存はそのまま再利用できます。
依存の解決はnpmやYarn 1とは異なり「自分のpackage.jsonに書いていないライブラリはimportできない」厳格な構造を取ります。これはnode_modulesのフラット化による「フライング依存」を防ぐ仕組みで、リリース後にライブラリ作者が依存を整理した瞬間に下流が壊れる事故を未然に減らせます。厳格すぎて既存プロジェクトで動かないライブラリがある場合はpublic-hoist-patternで限定的に外向きへ持ち上げる調整が可能です。
モノレポ向けの組込みワークスペース

pnpm-workspace.yamlを置けば、packages/*のようなパターンで配下のpackage.jsonをまとめて管理できます。pnpm -r buildでワークスペース内の全パッケージのbuildスクリプトを順序を考慮して実行でき、pnpm --filter ./apps/web... buildのように依存範囲を絞ったビルドも標準で可能です。Lernaが衰退気味の現在、フロントエンドモノレポではpnpm Workspace + Turborepo / Nxという組み合わせが定番化しています。
サブパッケージ間の依存は"my-utils": "workspace:^"のように書き、ローカルのソースを参照しつつ公開時にはSemVerの範囲指定に置き換える運用ができます。Viteの開発元evan-you氏らはpnpmのモノレポ運用を強く推奨しており、Vue・Vite・Nuxtのモノレポは実際にpnpmで管理されています。Reactチーム(Meta)のように独自構成を持つ大手以外では、新規モノレポでpnpmが第一選択肢に挙がるケースが増えています。
npmやYarnとの選び分け

Node.js付属のnpmは最も無難な選択肢で、公式ドキュメントもnpmコマンドを前提にしているため学習コストが最も低く済みます。Yarn Berry(Yarn 2/3/4)はPlug'n'Play(PnP)と呼ばれるnode_modulesを使わない独自方式で、より厳格な依存管理を目指していますが互換性問題でハマる場面もあります。Bunは2022年にJarred Sumner氏が公開したJavaScriptランタイム兼パッケージマネージャで、インストール速度では最先端ですがエコシステム互換性はpnpm/npmに分があります。
「省ディスクと再現性とモノレポ対応」が要件ならpnpm、「とにかく標準と互換性」ならnpm、「Yarn Berryで運用してきた既存リポジトリ」ならYarn Berry継続、というのが現実的な選び分けです。新規Node.jsプロジェクトでpnpmを選ぶ理由は今や明確で、特にモノレポ・大規模ワークスペースでは検討する価値が十分にあります。
まとめ
pnpmは2017年にZoltan Kochan氏が公開したNode.js向けパッケージマネージャで、コンテンツストア+ハードリンクの独自方式で省ディスクと高速性を両立しました。厳格な依存解決とpnpm-lock.yamlによる再現性、組込みのワークスペースでモノレポ運用にも適しています。npmやYarn・Bunと比較しつつ、Viteを含む主要OSSが採用する現代のフロントエンド標準として位置づけられます。
※本記事はIT用語辞典の手書きドラフトです。公開前に最新情報・出典を確認のうえ加筆修正してください。

コメント