AI時代の開発では npm より pnpm の方が良いかも
こんにちは、Sally 社 CTO の @aitaro です。 マーダーミステリーアプリ「ウズ」とマダミス情報サイト「マダミス.jp」を開発しています。
最近は Claude Code を使った AI Agent 駆動開発にどっぷり浸かっており、開発プロセス自体が大きく変わってきていることを実感しています。その中で、package manager の選択も見直す必要が出てきました。
はじめに
この記事では、AI Agent を活用した開発スタイルにおいて、なぜ npm より pnpm が有利になるのかを解説します。特に git worktree を活用した並列開発においては、pnpm のアーキテクチャ上の優位性が顕著に現れます。
なぜ今まで npm 使ってきたのか
弊社では、JavaScript のパッケージマネージャーとして npm を使い続けていました。yarn や pnpm という選択肢もありますが、効率的なチーム開発にはツールの統一が重要です。npm は古くから安定しており、Node.js の標準パッケージマネージャーとして、インターネット上に豊富な情報があります。新メンバーのオンボーディングやトラブルシューティングの際に、この点は大きなメリットでした。
実際、モノレポやマルチパッケージ構成では pnpm の方がパフォーマンスが優れていることは把握していました。しかし、当時の開発においてパフォーマンスがボトルネックになることはなく、あえて標準ツールから移行するリスクを取る必要性を感じていませんでした。
これまでの開発スタイルであれば、その判断は正しかったと思います。クローンしたレポジトリを単一のディレクトリで作業をする限り、npm install
を普段実行することはありません。また Turborepo によってモノレポの node_modules の一元管理も実現していたため、pnpm に移行してもディスク使用量の削減効果は限定的でした。CI/CD での依存関係のインストール時間が多少長くても、開発フロー全体から見れば許容範囲内でした。
AI Agent 駆動開発は git worktree を多用することになる
AI Agent を使った開発の一つの特徴は、複数のタスクを並列で処理できることです。Claude Code や GitHub Copilot などの AI ツールは、人間のように「一度に一つのことしかできない」という制約がありません。
従来の開発では、ブランチを切り替える度に作業が中断されていました。機能 A を開発中に緊急のバグ修正が入ると、変更を stash して、ブランチを切り替えて、npm install して...という一連の作業が必要でした。この間、開発はストップします。
しかし git worktree を使えば、物理的に異なるディレクトリで複数のブランチを同時に開けます。これにより、AI Agent が並列で作業することが可能になります。
# プロジェクト構造の例
project/
├── main/ # メインブランチ(本番環境)
├── feature-auth/ # 認証機能の実装(AI Agent 1)
├── feature-api/ # API設計の見直し(AI Agent 2)
├── bugfix-login/ # ログインバグ修正(AI Agent 3)
└── refactor-db/ # DB構造のリファクタリング(AI Agent 4)
それぞれのディレクトリで独立した Claude Code セッションを立ち上げることで、4 つのタスクを同時進行できます。これは人間のエンジニア 4 人が同時に作業しているのと同じ状態です。
実際に私も、バックエンドのパフォーマンス調査を Claude Code に任せている間に、別のセッションで新機能の実装を進める、といった並列作業が日常になっています。開発速度は体感で 3〜4 倍になりました。
npm と pnpm で node_modules の管理はどう違うのか
ここで問題になるのが、各 worktree での node_modules の管理です。
npm のアプローチ
npm は各プロジェクトディレクトリに独立した node_modules を作成します。worktree が 5 つあれば、同じパッケージが 5 回ダウンロードされ、5 箇所に保存されます。
project/
├── main/node_modules/ # React 19.1.0 (100MB)
├── feature-auth/node_modules/ # React 19.1.0 (100MB) ← 重複
├── feature-api/node_modules/ # React 19.1.0 (100MB) ← 重複
├── bugfix-login/node_modules/ # React 19.1.0 (100MB) ← 重複
└── refactor-db/node_modules/ # React 19.1.0 (100MB) ← 重複
大規模なプロジェクトでは node_modules が 1GB を超えることも珍しくありません。5 つの worktree があれば 5GB です。SSD の容量を圧迫するだけでなく、各 worktree での npm install にも時間がかかります。
pnpm のアプローチ
pnpm は npm とは異なるアプローチを取ります。パッケージの実体は ~/.pnpm-store
という共有ストアに一度だけ保存され、各プロジェクトの node_modules にはシンボリックリンクが作成されます。
~/.pnpm-store/
└── React 19.1.0 (100MB) # 実体は一つだけ
project/
├── main/node_modules/ # → ~/.pnpm-store へのリンク
├── feature-auth/node_modules/ # → ~/.pnpm-store へのリンク
├── feature-api/node_modules/ # → ~/.pnpm-store へのリンク
├── bugfix-login/node_modules/ # → ~/.pnpm-store へのリンク
└── refactor-db/node_modules/ # → ~/.pnpm-store へのリンク
worktree 間では依存関係がほぼ同じであるため、worktree を増やしてもディスク使用量はほとんど増えません。また、既にストアにあるパッケージは再ダウンロードの必要がないため、2 回目以降の install が高速化されます。
他にも pnpm には「厳格な依存解決」という特徴があります。npm では package.json に記載していないパッケージも暗黙的に使えてしまうことがありますが、pnpm ではそれができません。これにより、依存関係の問題を早期に発見できます。
速度・使用量の測定
実際に弊社のプロジェクトで測定した結果を紹介します。測定環境は MacBook Pro M1、プロジェクトは Turborepo を用いたモノレポ構成で、Next.js アプリケーションやバックエンドサーバー、UI コンポーネントライブラリ等が含まれています。依存パッケージは約 2,100 個です。
npm と pnpm のインストール時間の比較
# npm
❯ time npm i
npm i 34.74s user 36.33s system 177% cpu 39.937 total
# pnpm
❯ time pnpm i
pnpm i 6.80s user 37.14s system 320% cpu 13.715 total
pnpm の方が約 3 倍速いという結果になりました。
npm と pnpm の使用量の比較
rm -rf node_modules
の前後で df -m . | sed -n '1p;$p'
を実行し、自分の PC のディスク使用量の増分を測定しました。
- npm: 2,279 MB
- pnpm: 54MB
特に worktree を用いた並列開発では、worktree 間でほとんど依存関係は変わらないので、大きな効果が期待できることがわかりました。
これらの測定結果を表にまとめると以下のようになります。
項目 | npm | pnpm | 削減率 |
---|---|---|---|
インストール時間 | 39.9 秒 | 13.7 秒 | 約 66% |
ディスク使用量 | 2,279 MB | 54 MB | 約 98% |
インストール時間とディスク使用量の差は、従来の直列での開発では許容範囲かもしれません。しかし、AI Agent 駆動開発で複数の worktree を同時に扱う場合、この差が開発効率に大きく影響します。
まとめ
AI Agent 駆動開発では、複数のタスクを並列で処理することが当たり前になります。git worktree を活用して物理的に異なるディレクトリで作業することで、AI の並列処理能力を最大限に活かせます。
この開発スタイルにおいて、pnpm の共有ストアアーキテクチャは大きなアドバンテージとなります。ディスク容量の節約、インストール時間の短縮、厳格な依存管理により、worktree を用いた開発効率が向上します。
中規模以上のプロジェクトで AI Agent と共に本格的な並列開発を行うなら、pnpm への移行を検討する価値は十分にあります。
移行も思ったより簡単でした。pnpm import
で既存の package-lock.json から pnpm-lock.yaml を生成でき、あとは npm
を pnpm
に置き換えるだけです。
AI 時代の開発において、ツールの選択も進化する必要があります。皆さんの開発現場でも、ぜひ pnpm の導入を検討してみてください。
Discussion