JavaScript向けパッケージマネージャーのpnpmが、TypeScriptとNode.jsで動く従来実装をRustへ置き換えた。2026年8月26日に安定版となったpnpm 12は、コマンド、設定、pnpm-lock.yamlをpnpm 11から引き継ぎ、利用者に大がかりな移行を求めない設計である。その一方、処理時間の短縮幅はキャッシュの状態によって約44%から約97%まで開く。安定版公開後も互換性修正は続いており、導入時には「Rustだから速い」という説明より、どの作業が速くなり、どの既存コマンドを試すべきかを見極める必要がある。
4カ月で実験用バックエンドから安定版へ
Rust実装は、最初からpnpm全体を置き換えたわけではない。2026年4月25日に公開されたロードマップは、まず既存のpnpm-lock.yamlを読み、依存関係を新たに解決せずにnode_modulesを構築する「headless installer」をStage 1に置いた。依存関係の解決は従来のpnpmに残し、Rust側はパッケージの取得と配置に集中する分割だった。Stage 2で解決処理まで移す計画である。
5月20日のpnpm 11.2では、この境界を使った実験が始まった。@pnpm/pacquetを設定へ加えると、pnpmが依存関係を解決してロックファイルを書き、Rust実装のpacquetがファイルを取得して配置した。既存のロックファイルを両実装の契約にしたため、速度を上げる部分と互換性を保つ部分を切り離して試せた。
最初のpnpm 12リリース候補版は8月5日に出た。安定版はその21日後である。4月の段階別ロードマップから約4カ月で、取得と配置を受け持つ実験用バックエンドは、依存関係の解決からコマンド実行まで担うpnpm 12へ広がった。ただし、リポジトリ内ではpacquetという識別名が残る一方、利用者が実行するコマンドと公開製品名はpnpmのままである。
15msの再実行と4.29秒の新規インストール
2026年9月4日時点の公式ベンチマークには、pnpm 11.25.0とpnpm 12.3.2の比較がある。掲載値は直近3回のうち最速の結果で、遅延50ms・帯域200Mbpsに制限した同じレジストリへ各ツールを接続した。fixtureは、小さなファイルを大量に持つalotta-filesと、14種類のツール群で約1GBの依存関係を構成するalotta-packagesに分かれる。両者の絶対時間は比較せず、同じfixture内で世代差を見る必要がある。
| 条件 | fixture | pnpm 11 | pnpm 12 | 所要時間の短縮率 |
|---|---|---|---|---|
| キャッシュもロックファイルもない新規インストール | alotta-files | 7.67秒 | 4.29秒 | 44.1% |
| 変更なしの再実行 | alotta-files | 469ms | 15ms | 96.8% |
| 依存関係の更新 | alotta-files | 3.54秒 | 1.00秒 | 71.8% |
| キャッシュもロックファイルもない新規インストール | alotta-packages | 24.3秒 | 13.6秒 | 44.0% |
| 変更なしの再実行 | alotta-packages | 457ms | 18ms | 96.1% |
| 依存関係の更新 | alotta-packages | 12.0秒 | 3.34秒 | 72.2% |
表の短縮率は、各行について(pnpm 11の時間−pnpm 12の時間)÷pnpm 11の時間で算出した。新規インストールの短縮率は約44%で、依存関係を更新すると約72%、何も変わっていない再実行では約96〜97%へ広がる。最後の条件ではキャッシュ、ロックファイル、node_modulesがすべて存在する。pnpm 12の15〜18msという値は、初回導入の所要時間ではなく、同じ作業環境で依存関係を変えずに再び実行した際の数字である。
VercelのTurborepo移行は、別の大規模ワークスペースで速度差を測っている。対象は21プロジェクト、1670パッケージで、pnpm 10.28.0と12.0.0をLinux x86_64・XFS上で各20回実行した。順序を入れ替えた4ブロックの中央値では、6条件の短縮率が64.4〜90.5%となった。node_modulesがある実行は1.476秒から142msへ、ストアもnode_modulesもなくライフサイクルスクリプトを動かす実行は9.850秒から3.472秒へ縮んだ。
一方で、ネイティブ実行ファイルを含むCorepackの取得物は17.5MBから47.3MBへ増えた。Vercelの測定では、Corepackキャッシュが空の起動が711msから789msへ11.1%遅くなり、キャッシュ済みの起動は261msから66.8msへ74.7%速くなった。pnpmストアとnode_modulesの割り当て済み容量も3.891GBから1.850GBへ52.5%減ったが、これはハードリンクを考慮したXFS上の結果である。反復実行の速度、初回取得、ディスク容量は別々の条件として判断すべきだ。
Node.jsを外し、ロックファイルの作り方も変えた
pnpmの基本設計はRust化より前から変わっていない。パッケージの実体を内容アドレス方式のストアへ保存し、複数プロジェクトのnode_modulesにはハードリンクやコピー・オン・ライトで配置する。同じファイルをプロジェクトごとに重ねて保存しない仕組みが、ディスク効率と厳密な依存関係分離を支えてきた。pnpm 12はこの配置モデルを維持したまま、依存解決とファイル処理をネイティブ実行ファイルへ移した。
変更なしの再実行で差が大きい理由として、固定費の比重が考えられる。ネットワーク転送がない場面では、JavaScriptランタイムの起動、状態の読み出し、リンクの確認が処理時間に占める割合は相対的に増える。ネイティブ化はこの経路を短くし得るが、公式測定はCPUプロファイルによる因果分析ではない。pnpm 12にはアルゴリズムとファイル配置の変更も含まれるため、約97%の短縮をRustだけの効果とは断定できない。
代表例が循環する依存グラフの扱いだ。pnpm 12はパッケージID順に並べ、循環を切る位置を固定した。同じ依存グラフなら、ワークスペース内の並びや探索順が変わっても同一バイトのロックファイルを生成する。公式測定では循環が多い大規模ワークスペースでピア依存関係の解決が2〜3倍速く、メモリ使用量は約25%減った。既存ロックファイルは使えるが、再解決する最初のインストールでは一度だけ変更が生じる。
「移行不要」はどこまで通用するか
pnpmチームは安定版を出す前に、n8n、Next.js、Viteなど10件の大規模な公開ワークスペースでRust版を検証した。凍結ロックファイルを使う新規と反復インストールに加え、ロックファイルの再生成、各リポジトリのbuild・lint・testを確認する手順である。10件は少なくとも1つのOSで主要手順を通過したと記録されている。VercelのTurborepo移行も8月29日にマージされ、pnpm 12が実プロジェクトで動く材料はそろっている。
それでも、「pnpm 11のフラグを引き継ぐ」という約束には修正が必要だった。8月28日にマージされたPRでは、pnpm 11が受理した16個の設定フラグをRust版の引数解析が拒否していた問題を直した。--package-import-methodや--child-concurrencyなどが対象で、値のありなしとコマンド上の位置をpnpm 11へ合わせた。
9月4日の12.3.4でも、--unsafe-perm、--offline、--dangerously-allow-all-buildsといった真偽値の設定フラグが修正された。Vercelのビルドはpnpm install --unsafe-permを使うため、修正前のpnpm 12では全インストールが引数エラーで止まっていた。公開リポジトリでの検証を通っても、組織固有のCI引数までは覆い切れない。
互換性のあるロックファイルと、すべてのコマンドが同じ意味で通ることは別の問題である。pnpm install --resolution-onlyは削除され、ピア依存関係の確認はpnpm peers checkへ移った。GitHub、GitLab、BitbucketのGit依存関係は正規化されたHTTPS URLがロックファイルに入り、非公開リポジトリをSSHで取得する場合はGit側のURL書き換え設定が必要になる。既存CIは、設定ファイルと実際のコマンド列を固定した上でpnpm 12を試すべきだ。
安定版と既定配布のねじれ
pnpm 12は安定版だが、2026年9月5日時点でnpmのlatestタグはpnpm 11を指す。pnpm 11.10.0以降の利用者はpnpm self-update next-12で切り替えられる。Homebrewとwinget、ScoopとChocolateyは、まだpnpm 12を提供していない。安定性の区分と、広い配布経路で既定になる時期が分かれている。
導入経路によってNode.jsの要件も変わる。npx get-pnpm next-12を使うインストール処理にはNode.js 22.13以降が必要だが、導入後のpnpm 12はネイティブ実行ファイルなのでNode.jsなしで動く。スタンドアロンスクリプトなら導入時にもNode.jsは要らない。pnpm 11のスタンドアロン版で動かなかったIntel Mac向け実行ファイルも復活した。
導入判断を最大短縮率だけで決めると、Corepack初回取得の遅さやCLI引数の差を見落とす。まずCIでpnpmのバージョンを12.3.4以降へ固定し、普段使うインストール、更新、公開前検査を同じ引数で走らせる。その条件を通過し、キャッシュ済みの反復作業で短縮が再現できれば、Rust化は開発者が一日に何度も支払う待ち時間を確実に減らせる。
