pnpm に切り替えたら node_modules のサイズが激減した話

npm から pnpm に移行したところ、node_modules のディスク使用量が半分以下になり、インストール速度もかなり速くなりました。モノレポ対応や切り替え手順、使ってみた感想をまとめます。

🙌 結論から

npm から pnpm に切り替えただけで、node_modules のディスク容量がざっくり半分以下になりました!

pnpm はパッケージをグローバルなコンテンツアドレス可能なストアに一度だけ保存し、各プロジェクトにはハードリンクを張る仕組みです。

複数プロジェクトで同じパッケージを使っていても、ストレージは 1 カ所分しか消費しないため、開発環境のディスク節約にかなり効果的です(^^)

コマンドも npm とほぼ同じなので、移行のハードルはかなり低かったです。


👀 乗り換えたきっかけ

いくつかのプロジェクトを並行して管理していたとき、node_modules がディスクを圧迫していることが気になり始めました。

du -sh */node_modules で使用量を確認したところ、各プロジェクトが 500MB 〜 1GB 以上を消費していて、合計 10GB 近くになっていたんです(・_・;)

また npm install の時間も長く、CI でも毎回フルインストールが走るため待ち時間がかなりありました。

そんなときに pnpm を改めて調べてみて、「グローバルストアで重複排除する」という仕組みに興味を持ったのが乗り換えのきっかけです。


💡 切り替え手順

まずは pnpm 自体をインストールします。

npm install -g pnpm

既存プロジェクトでは、npm install の代わりに pnpm install を実行するだけです!

# npm の場合
npm install
npm run dev

# pnpm に切り替えるだけ(package.json の変更は不要)
pnpm install
pnpm dev

package.json の書き換えは不要で、既存の設定ファイルをそのまま使えます。

モノレポを構成する場合は、ルートに pnpm-workspace.yaml を 1 ファイル置くだけでパッケージ間の連携が有効になります。

# pnpm-workspace.yaml
packages:
  - 'apps/*'
  - 'packages/*'

これで workspace:* によるローカルパッケージの参照が使えるようになります。


✅ 使ってみた感想

切り替えてまず驚いたのは、インストール速度でした。

pnpm install が体感で npm の 2〜3 倍速く完了します!

グローバルストアにキャッシュされているパッケージはダウンロードが不要なので、2 回目以降はさらに高速です。

ディスク使用量についても、4 プロジェクト分を pnpm に移行したところ、合計 8GB あった node_modules が 3GB 台まで減りました(^o^)/

一方で、移行時にハマった点もあります。

  • 厳格なパス解決: pnpm の node_modules 構造は npm/yarn と異なり、package.json に書いていない依存パッケージを直接 require するとエラーになります。
  • 一部の古いツールとの互換性: create-react-app など古いツールでは動作しないケースがありました。最近のエコシステムでは基本的に問題ありません。

全体的に、移行して後悔はまったくなく「もっと早く切り替えればよかった」という感想です(`・ω・´)


📚 catalogでモノレポのバージョンを一元管理する

複数プロジェクトを pnpm-workspace.yaml で1つのモノレポにまとめてから、新しい悩みが出てきました。

「apps/web は React 19、apps/admin はまだ React 18」のように、パッケージごとにバージョンがバラバラになっていく問題です。

これを解決してくれたのが catalog 機能です。

# pnpm-workspace.yaml
catalog:
  react: ^19.0.0
  typescript: ^5.8.0

packages:
  - 'apps/*'
  - 'packages/*'

各パッケージの package.json では、バージョン番号の代わりに catalog: と書くだけです。

{
  "dependencies": {
    "react": "catalog:",
    "typescript": "catalog:"
  }
}

こうしておくと、pnpm-workspace.yaml の1箇所を書き換えるだけで、参照している全パッケージのバージョンが一斉に揃います(・∀・)

以前は「このパッケージだけReactのバージョンが古いままだった」という事故が何度かあったんですが、catalogを導入してからはバージョンのズレそのものが構造的に起きなくなりました

catalogMode: strict を設定しておくと、pnpm add で新しい依存を追加したときに自動で catalog: 形式に揃えてくれるので、チームメンバーが手癖でバージョン番号を直接書いてしまう事故も防げます。

モノレポで複数パッケージを管理していて「バージョンのブレ」に悩んだことがある人には、真っ先に試してほしい機能です!

パパ系Webエンジニア〜愛用ガジェット一覧 🛍️

この記事を書いている作業環境のガジェットを楽天ROOMにまとめています ✨ 在宅エンジニアのデスク作りの参考にどうぞ 🙌

🙌 まとめ

  • pnpm はグローバルストアでパッケージを管理し、ディスク使用量を大幅に削減できる
  • コマンドが npm とほぼ同じで、package.json の変更なしに移行できる
  • インストール速度が速く、CI の待ち時間削減にも繋がる
  • モノレポ対応は pnpm-workspace.yaml 1 ファイルで完結する
  • 古いツールとの互換性には注意が必要なケースがある

npm をまだ使っているプロジェクトがあれば、まず 1 つだけ試してみることをおすすめします🚀

ディスクの空き容量が増えると、意外と気分がいいものですよ!

※ pnpmのバージョンによって使える機能が異なります。最新情報は pnpm公式ドキュメント をご確認ください👀