pnpm vs npm vs yarn
JavaScript パッケージマネージャーの技術的比較
pnpmnpmyarn類似パッケージ:

JavaScript パッケージマネージャーの技術的比較

npmpnpmyarn は JavaScript/TypeScript プロジェクトの依存関係を管理するためのパッケージマネージャーです。これらはパッケージのインストール、バージョン解決、スクリプト実行、モノレポ対応などの機能を提供し、現代のフロントエンド開発ワークフローを支える基盤となっています。npm は Node.js に標準搭載されており最も広く使われていますが、pnpm はディスク効率と高速インストールを特徴とし、yarn(特に Berry 以降)は Plug’n’Play やプラグインシステムによる高度なカスタマイズを可能にしています。

npmのダウンロードトレンド

3 年

GitHub Starsランキング

統計詳細

パッケージ
ダウンロード数
Stars
サイズ
Issues
公開日時
ライセンス
pnpm54,208,95234,18118.7 MB2,1381日前MIT
npm13,145,4769,54411 MB6342日前Artistic-2.0
yarn8,412,74541,5355.34 MB2,0612年前BSD-2-Clause

npm vs pnpm vs Yarn: パッケージマネージャーの技術的比較

JavaScriptエコシステムにおけるパッケージマネージャーは、依存関係の解決、インストール、スクリプト実行など、開発ワークフローの根幹を支えています。npmpnpmyarn はいずれも広く使われているツールですが、内部アーキテクチャや開発体験(DX)には明確な違いがあります。この記事では、プロフェッショナルなフロントエンド開発者の視点から、実際のエンジニアリング課題に即した技術的比較を行います。

📦 依存関係の管理方式:コピー vs シンボリックリンク vs ハードリンク

npm は従来の「ネストされた node_modules」方式を採用しています。各パッケージが自身の依存関係を再帰的に node_modules に配置するため、ディスク使用量が膨大になりやすく、重複インストールが発生します。

# npm install の結果(例)
node_modules/
├── lodash/
└── express/
    └── node_modules/
        └── lodash/  # 同じ lodash が複数回インストールされる可能性あり

pnpm は「コンテンツアドレス可能なストア」を用いて、すべてのパッケージをグローバルに1回だけ保存し、プロジェクト内ではシンボリックリンクとハードリンクで参照します。これにより、ディスク使用量が劇的に削減され、node_modules の構造もフラットになります。

# pnpm install の結果(例)
node_modules/
├── .pnpm/
│   ├── lodash@4.17.21 → /store/v3/lodash/4.17.21
│   └── express@4.18.2 → /store/v3/express/4.18.2
└── lodash → .pnpm/lodash@4.17.21/node_modules/lodash

yarn(Classic および Berry)は、Yarn Classic では npm と似たネスト方式でしたが、Yarn Berry(v2+)では Plug’n’Play(PnP)という新しい方式を導入しました。PnP では node_modules を完全に排除し、.pnp.cjs というファイルで依存関係を記述し、Node.js のモジュール解決をフックして直接パッケージストアから読み込みます。

# yarn install (Berry/PnP) の結果(例)
.pnp.cjs          # 依存関係マップ
.yarn/cache/      # 圧縮されたパッケージキャッシュ

💡 注意:Yarn Classic(v1)は依然としてメンテナンスされていますが、新規プロジェクトでは Yarn Berry(v2+)が推奨されています。本比較では Yarn Berry を前提とします。

⚡ インストール速度とディスク効率

npm は v7 以降でワークスペース(monorepo)サポートや --prefer-dedupe オプションを追加し、改善されていますが、依然として大量のファイルI/Oを伴うため、大規模プロジェクトでは遅くなりがちです。

# npm のワークスペース設定(package.json)
{
  "workspaces": ["packages/*"]
}

pnpm はハードリンクとシンボリックリンクにより、同じパッケージを複数プロジェクトで共有してもディスク容量を節約できます。また、node_modules がフラットなため、Node.js のモジュール解決も高速です。

# pnpm のワークスペース設定(pnpm-workspace.yaml)
packages:
  - 'packages/*'

yarn(Berry)の PnP 方式は、node_modules の作成をスキップするため、インストールが非常に高速です。ただし、一部のツール(特に古いBabelプラグインやESLint設定)が PnP に対応していない場合があり、互換性レイヤー(node-modules プラグイン)を使う必要があります。

# yarn のワークスペース設定(package.json)
{
  "workspaces": ["packages/*"]
}

🔒 モノレポとワークスペースの扱い

すべてのパッケージマネージャーはモノレポをサポートしていますが、その設計思想は異なります。

npm のワークスペースはシンプルで、ルートの package.jsonworkspaces フィールドを定義するだけで、各パッケージ間のリンクが自動的に行われます。

# npm でのパッケージ間依存
# packages/app/package.json
{
  "dependencies": {
    "ui-components": "workspace:*"
  }
}

pnpm も同様に workspace:* 構文をサポートし、さらに pnpm install -r で全ワークスペースを一括インストールできます。また、pnpm recursive コマンド(旧称)で全パッケージにコマンドを実行可能です。

# pnpm での全パッケージテスト実行
pnpm -r test

yarn(Berry)は yarn workspaces foreach で全ワークスペースにコマンドを実行でき、より柔軟なフィルタリング(--include--exclude)が可能です。

# yarn での全パッケージビルド(ただし test-* 以外)
yarn workspaces foreach --exclude "test-*" run build

🛠️ スクリプト実行と拡張性

npmnpm run でスクリプトを実行し、npm exec(または npx)でローカル/グローバルコマンドを実行できます。拡張性は限定的で、主に scripts フィールドとライフサイクルフックに依存します。

// package.json
{
  "scripts": {
    "dev": "vite",
    "postinstall": "husky install"
  }
}

pnpmpnpm run でスクリプトを実行し、pnpm dlx で一時的なコマンド実行をサポートします。また、pnpmfile.js(旧)や hooks(v8+)で依存関係解決をカスタマイズできます。

// .pnpmfile.cjs(例:特定パッケージの依存を上書き)
module.exports = {
  hooks: {
    readPackage(pkg) {
      if (pkg.name === 'problematic-lib') {
        pkg.dependencies = { ...pkg.dependencies, 'lodash': '^4.17.21' };
      }
      return pkg;
    }
  }
};

yarn(Berry)は yarn run でスクリプトを実行し、yarn dlx で一時コマンドを実行します。さらに、Yarn はプラグインシステムを備えており、@yarnpkg/plugin-* で機能を拡張できます(例:plugin-interactive-tools で対話型アップグレード)。

# yarn の対話型依存更新
yarn up -i

🔄 依存関係の更新とセキュリティ

npmnpm audit で脆弱性をチェックし、npm update で依存を更新できます。ただし、package-lock.json の競合解決は手動で行う必要があることが多いです。

npm audit
npm update lodash

pnpmpnpm audit(内部で npm audit をラップ)で脆弱性をチェックし、pnpm update で更新します。pnpm outdated で更新可能なパッケージを確認可能です。

pnpm audit
pnpm update --latest

yarn(Berry)は yarn npm audit で脆弱性をチェックし、yarn up で依存を更新します。yarn dedupe で重複を最適化することもできます。

yarn npm audit
yarn up lodash@latest

🌐 オフラインとキャッシュ戦略

npm~/.npm にキャッシュを保存し、オフラインでも npm ci が可能ですが、ロックファイルがないと不安定です。

pnpm はグローバルストア(~/.pnpm-store)にすべてのパッケージを保存するため、同じバージョンのパッケージはネットワークアクセスなしで再利用できます。

yarn(Berry)は .yarn/cache に圧縮されたパッケージを保存し、.yarnrc.yml でキャッシュ戦略をカスタマイズできます。また、Zero-Installs(.yarn/cache をリポジトリに含める)により、yarn install が不要になるケースもあります。

# .yarnrc.yml
enableGlobalCache: false

📊 実際の選択基準:チームとプロジェクトに合わせて

大規模モノレポでディスク容量を節約したい場合

pnpm が最適です。ハードリンクによるストレージ効率と、フラットな node_modules による高速解決が魅力です。

最新技術を積極的に取り入れ、高度なカスタマイズが必要な場合

yarn(Berry)が向いています。PnP、プラグインシステム、Zero-Installs などの先進機能が活きます。

汎用性と安定性を重視し、学習コストを最小限に抑えたい場合

npm が無難です。Node.js 標準搭載で、ほとんどのCI/CD環境やツールがネイティブサポートしています。

📌 まとめ:主な違い一覧

特徴npmpnpmyarn(Berry)
依存管理方式ネストされた node_modulesグローバルストア + シンボリックリンクPnP(.pnp.cjs
ディスク効率低(重複あり)非常に高い高(キャッシュ圧縮)
インストール速度中〜低非常に高い(PnP時)
モノレポサポートあり(シンプル)あり(強力)あり(柔軟)
拡張性限定的フックでカスタマイズプラグインシステム
互換性最高(標準)高(node_modules あり)中(PnP非対応ツールあり)

💡 結論

  • npm は「何も考えずに使える安心感」が強み。社内ツールや小〜中規模プロジェクトに最適。
  • pnpm は「効率と整合性」を追求。大規模モノレポやCI環境での高速化が求められる場面で真価を発揮。
  • yarn(Berry)は「最先端と制御力」が売り。高度なワークフローを構築したいチーム向け。

最終的には、チームのスキルセット、既存ツールチェーン、プロジェクト規模を総合的に判断して選ぶべきです。どれも成熟したツールであり、正解は「あなたのプロジェクトに最もフィットするもの」です。

選び方: pnpm vs npm vs yarn

  • pnpm:

    pnpm を選ぶべきは、ディスク効率とインストール速度が重要な大規模プロジェクトやモノレポの場合です。ハードリンクとシンボリックリンクによるグローバルストア方式で、同じパッケージを複数プロジェクトで共有してもストレージを節約できます。また、フラットな node_modules により Node.js のモジュール解決も高速です。ただし、極めて古いツールとの互換性問題がまれに発生する可能性があります。

  • npm:

    npm を選ぶべきは、プロジェクトのシンプルさと汎用性を重視する場合です。Node.js 標準搭載で、あらゆるCI環境やツールがネイティブサポートしており、学習コストがほぼゼロです。小〜中規模プロジェクトや、外部ライブラリとの互換性を最優先したいチームに最適です。ただし、大規模モノレポではディスク使用量やインストール時間が課題になることがあります。

  • yarn:

    yarn(Berry)を選ぶべきは、最新技術を積極的に取り入れ、ワークフローを細かく制御したい場合です。Plug’n’Play(PnP)による node_modules 不要の高速インストール、プラグインシステムによる拡張性、Zero-Installs による再現性向上が特徴です。ただし、PnP に対応していないサードパーティツールがまだ存在するため、互換性レイヤーの設定が必要になることがあります。

pnpm のREADME

简体中文 | 日本語 | 한국어 | Italiano | Português Brasileiro

pnpm

Fast, disk space efficient package manager:

  • Fast. Up to 2x faster than the alternatives (see benchmark).
  • Efficient. Files inside node_modules are linked from a single content-addressable storage.
  • Great for monorepos.
  • Strict. A package can access only dependencies that are specified in its package.json.
  • Deterministic. Has a lockfile called pnpm-lock.yaml.
  • Works as a Node.js version manager. See pnpm env use.
  • Works everywhere. Supports Windows, Linux, and macOS.
  • Battle-tested. Used in production by teams of all sizes since 2016.
  • See the full feature comparison with npm and Yarn.

To quote the Rush team:

Microsoft uses pnpm in Rush repos with hundreds of projects and hundreds of PRs per day, and we’ve found it to be very fast and reliable.

npm version OpenCollective OpenCollective X Follow Stand With Ukraine

Platinum Sponsors

Bit

Gold Sponsors

Sanity Discord Vite
SerpApi CodeRabbit Workleap
Stackblitz Nx

Silver Sponsors

u|screen Leniolabs_ Depot
devowl.io Cerbos OOMOL Studio

Support this project by becoming a sponsor.

Background

pnpm uses a content-addressable filesystem to store all files from all module directories on a disk. When using npm, if you have 100 projects using lodash, you will have 100 copies of lodash on disk. With pnpm, lodash will be stored in a content-addressable storage, so:

  1. If you depend on different versions of lodash, only the files that differ are added to the store. If lodash has 100 files, and a new version has a change only in one of those files, pnpm update will only add 1 new file to the storage.
  2. All the files are saved in a single place on the disk. When packages are installed, their files are linked from that single place consuming no additional disk space. Linking is performed using either hard-links or reflinks (copy-on-write).

As a result, you save gigabytes of space on your disk and you have a lot faster installations! If you'd like more details about the unique node_modules structure that pnpm creates and why it works fine with the Node.js ecosystem, read this small article: Flat node_modules is not the only way.

💖 Like this project? Let people know with a tweet

Installation

For installation options visit our website.

Usage

Just use pnpm in place of npm/Yarn. E.g., install dependencies via:

pnpm install

For more advanced usage, read pnpm CLI on our website, or run pnpm help.

Benchmark

pnpm is up to 2x faster than npm and Yarn classic. See all benchmarks here.

Benchmarks on an app with lots of dependencies:

Support

License

MIT