pnpmは、npmと互換性のある高速なパッケージマネージャーです。ディスク容量を節約し、依存関係のインストールを高速化できます。
インストール方法
npmでインストール
npm install -g pnpm
curlでインストール(推奨)
curl -fsSL https://get.pnpm.io/install.sh | sh -
Homebrewでインストール(macOS/Linux)
brew install pnpm
バージョン確認
pnpm --version
基本的な使い方
プロジェクトの初期化
# 新規プロジェクトを作成
pnpm init
# package.jsonが生成される
パッケージのインストール
# package.jsonの依存関係をすべてインストール
pnpm install
# または
pnpm i
パッケージの追加
# 本番用の依存関係として追加
pnpm add <package>
# 例:Expressをインストール
pnpm add express
# 複数のパッケージを追加
pnpm add react react-dom
# 開発用の依存関係として追加
pnpm add -D <package>
# または
pnpm add --save-dev <package>
# 例:TypeScriptを開発用依存関係として追加
pnpm add -D typescript
パッケージの削除
# パッケージを削除
pnpm remove <package>
# または
pnpm rm <package>
# 例:lodashを削除
pnpm remove lodash
パッケージの更新
# すべてのパッケージを更新
pnpm update
# 特定のパッケージを更新
pnpm update <package>
# 例:Reactを更新
pnpm update react
# 最新版に更新(semverの範囲を超えて)
pnpm update --latest
スクリプトの実行
# package.jsonのscriptsを実行
pnpm run <script>
# 例:devスクリプトを実行
pnpm run dev
# 省略形(run不要)
pnpm dev
pnpm test
pnpm build
グローバルインストール
# グローバルにパッケージをインストール
pnpm add -g <package>
# 例:TypeScriptをグローバルにインストール
pnpm add -g typescript
よく使うコマンド
pnpm install(i)
# package.jsonの依存関係をインストール
pnpm install
# pnpm-lock.yamlを無視してインストール
pnpm install --no-frozen-lockfile
# node_modulesを削除してクリーンインストール
rm -rf node_modules pnpm-lock.yaml
pnpm install
pnpm add
# 本番用依存関係として追加
pnpm add express
# 開発用依存関係として追加
pnpm add -D jest
# ピア依存関係として追加
pnpm add -P react
# オプショナル依存関係として追加
pnpm add -O canvas
# 特定のバージョンを指定
pnpm add express@4.18.0
# 最新版を指定
pnpm add express@latest
# バージョン範囲を指定
pnpm add "express@^4.0.0"
pnpm update(up)
# すべてのパッケージを更新
pnpm update
# 対話的に更新するパッケージを選択
pnpm update --interactive
# 最新版に更新
pnpm update --latest
# または
pnpm up -L
# 再帰的に依存関係を更新
pnpm update --recursive
pnpm list(ls)
# インストール済みパッケージを表示
pnpm list
# 最上位の依存関係のみ表示
pnpm list --depth 0
# 特定のパッケージを検索
pnpm list express
# JSON形式で出力
pnpm list --json
# グローバルパッケージを表示
pnpm list -g
pnpm outdated
# 古いパッケージを確認
pnpm outdated
# JSON形式で出力
pnpm outdated --json
pnpm why
# なぜそのパッケージがインストールされているか確認
pnpm why <package>
# 例:lodashがなぜインストールされているか
pnpm why lodash
ワークスペース機能
pnpm-workspace.yaml の作成
packages:
- 'packages/*'
- 'apps/*'
ワークスペースでのパッケージ管理
# すべてのワークスペースで依存関係をインストール
pnpm install
# 特定のワークスペースにパッケージを追加
pnpm add <package> --filter <workspace>
# 例:@myapp/apiワークスペースにexpressを追加
pnpm add express --filter @myapp/api
# すべてのワークスペースでスクリプトを実行
pnpm -r run build
# 並列実行
pnpm -r --parallel run test
ワークスペース内のパッケージ参照
{
"dependencies": {
"@myapp/utils": "workspace:*"
}
}
# ワークスペース内のパッケージを追加
pnpm add @myapp/utils --workspace
便利なコマンド
pnpm exec
# node_modules/.binのコマンドを実行
pnpm exec <command>
# 例:tscを実行
pnpm exec tsc
# 省略形(pnpm dlx)
pnpm dlx create-react-app my-app
pnpm dlx
# パッケージをインストールせずに一度だけ実行(npxと同等)
pnpm dlx <package>
# 例:create-viteを実行
pnpm dlx create-vite@latest
pnpm store
# ストアの場所を表示
pnpm store path
# 未使用のパッケージを削除
pnpm store prune
# ストアの状態を確認
pnpm store status
pnpm audit
# 脆弱性をチェック
pnpm audit
# 自動修正
pnpm audit --fix
pnpm patch
# パッケージにパッチを適用
pnpm patch <package>@<version>
# 例:react@18.2.0にパッチを適用
pnpm patch react@18.2.0
# → 一時ディレクトリが作成される
# → ファイルを編集
# → 以下のコマンドを実行
pnpm patch-commit /tmp/patch-dir
pnpm設定
.npmrcで設定
# ストアのディレクトリを指定
store-dir=~/.pnpm-store
# symlink(シンボリックリンク)を使用
node-linker=isolated
# フラットなnode_modulesを使用(npmと同じ構造)
node-linker=hoisted
# 厳格なピア依存関係チェック
strict-peer-dependencies=true
# インストール時の進行状況を表示しない
progress=false
# レジストリを指定
registry=https://registry.npmjs.org/
設定コマンド
# 設定を表示
pnpm config list
# 設定を取得
pnpm config get <key>
# 設定を変更
pnpm config set <key> <value>
# 例:ストアディレクトリを変更
pnpm config set store-dir ~/.pnpm-store
# 設定を削除
pnpm config delete <key>
npm/yarnからの移行
package-lock.json / yarn.lock から移行
# npmから移行
pnpm import
# package-lock.jsonからpnpm-lock.yamlが生成される
scripts の置き換え
npmやyarnのscriptsはpnpmでそのまま動作します。
{
"scripts": {
"dev": "vite",
"build": "vite build",
"test": "jest"
}
}
# npm run dev → pnpm dev
pnpm dev
# npm run build → pnpm build
pnpm build
# npm test → pnpm test
pnpm test
実践的な使い方
プロジェクト開始時
# プロジェクトディレクトリを作成
mkdir my-project
cd my-project
# package.jsonを作成
pnpm init
# パッケージを追加
pnpm add express
pnpm add -D typescript @types/node @types/express
# TypeScript設定を作成
pnpm exec tsc --init
既存プロジェクトでの使用
# リポジトリをクローン
git clone https://github.com/user/repo.git
cd repo
# 依存関係をインストール
pnpm install
# 開発サーバーを起動
pnpm dev
パッケージの更新確認と実行
# 古いパッケージを確認
pnpm outdated
# 対話的に更新
pnpm update --interactive
# または、最新版に更新
pnpm update --latest
グローバルパッケージの管理
# グローバルパッケージをインストール
pnpm add -g typescript ts-node nodemon
# グローバルパッケージを確認
pnpm list -g --depth 0
# グローバルパッケージを更新
pnpm update -g typescript
トラブルシューティング
依存関係の競合
# node_modulesとロックファイルを削除して再インストール
rm -rf node_modules pnpm-lock.yaml
pnpm install
キャッシュのクリア
# ストアをクリーンアップ
pnpm store prune
# 完全に削除
rm -rf ~/.pnpm-store
ピア依存関係のエラー
# ピア依存関係を自動インストール
auto-install-peers=true
# または、厳格なチェックを無効化
strict-peer-dependencies=false
シンボリックリンクの問題
# フラットなnode_modulesを使用
node-linker=hoisted
インストールが遅い場合
# ネットワークの並列実行数を増やす
pnpm install --network-concurrency=10
# または、.npmrcで設定
echo "network-concurrency=10" >> .npmrc
なぜpnpmが高速で効率的なのか
ディスク容量の節約
npmやyarnは、プロジェクトごとにnode_modulesにパッケージをコピーします。pnpmは、グローバルストアに1つだけパッケージを保存し、プロジェクトからはハードリンクを作成します。
# npmの場合
project1/node_modules/react/ (50MB)
project2/node_modules/react/ (50MB)
project3/node_modules/react/ (50MB)
合計: 150MB
# pnpmの場合
~/.pnpm-store/react/ (50MB)
project1/node_modules/react/ → ハードリンク
project2/node_modules/react/ → ハードリンク
project3/node_modules/react/ → ハードリンク
合計: 50MB
インストールの高速化
パッケージがすでにストアにある場合、ネットワークからのダウンロードが不要で、ハードリンクを作成するだけで済みます。
# 初回インストール(ダウンロードが必要)
pnpm install # 30秒
# 2回目以降(ストアから再利用)
pnpm install # 5秒
厳格な依存関係管理
pnpmは、package.jsonに明示的に記載された依存関係のみにアクセスできます。npmやyarnでは、直接の依存関係でなくても、他のパッケージの依存関係にアクセスできてしまう問題(Phantom dependencies)がありました。
// npmの場合(問題あり)
// package.jsonにlodashがなくても動作してしまう
import _ from 'lodash'; // 他のパッケージがlodashに依存している場合
// pnpmの場合(正しく動作)
// package.jsonにlodashがない場合はエラー
import _ from 'lodash'; // Error: Cannot find module 'lodash'
モノレポのサポート
pnpmはワークスペース機能を標準でサポートしており、複数のパッケージを含むモノレポを簡単に管理できます。
packages:
- 'packages/*'
- 'apps/*'
# すべてのワークスペースで依存関係をインストール
pnpm install
# すべてのワークスペースでビルド
pnpm -r run build
npmとpnpmのコマンド対応表
npm | pnpm
------------------------------|------------------------------
npm install | pnpm install
npm install <package> | pnpm add <package>
npm install -D <package> | pnpm add -D <package>
npm install -g <package> | pnpm add -g <package>
npm uninstall <package> | pnpm remove <package>
npm update | pnpm update
npm run <script> | pnpm <script>
npx <command> | pnpm dlx <command>
npm list | pnpm list
npm outdated | pnpm outdated
npm audit | pnpm audit
npm init | pnpm init
yarnとpnpmのコマンド対応表
yarn | pnpm
------------------------------|------------------------------
yarn | pnpm install
yarn add <package> | pnpm add <package>
yarn add -D <package> | pnpm add -D <package>
yarn global add <package> | pnpm add -g <package>
yarn remove <package> | pnpm remove <package>
yarn upgrade | pnpm update
yarn <script> | pnpm <script>
yarn dlx <command> | pnpm dlx <command>
yarn list | pnpm list
yarn outdated | pnpm outdated
yarn audit | pnpm audit
yarn init | pnpm init
yarn workspaces info | pnpm list -r --depth -1
CIでの使用
GitHub Actions
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: 8
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Run tests
run: pnpm test
- name: Build
run: pnpm build
GitLab CI
image: node:20
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- .pnpm-store
before_script:
- curl -fsSL https://get.pnpm.io/install.sh | sh -
- pnpm config set store-dir .pnpm-store
- pnpm install --frozen-lockfile
test:
script:
- pnpm test
build:
script:
- pnpm build
Dockerでの使用
FROM node:20-alpine
# pnpmをインストール
RUN corepack enable && corepack prepare pnpm@latest --activate
WORKDIR /app
# 依存関係ファイルをコピー
COPY package.json pnpm-lock.yaml ./
# 依存関係をインストール
RUN pnpm install --frozen-lockfile --prod
# ソースコードをコピー
COPY . .
# ビルド
RUN pnpm build
CMD ["pnpm", "start"]
パフォーマンス比較
インストール速度
# 100個の依存関係を持つプロジェクト
npm install(キャッシュなし): 45秒
yarn install(キャッシュなし): 35秒
pnpm install(キャッシュなし): 30秒
npm install(キャッシュあり): 20秒
yarn install(キャッシュあり): 15秒
pnpm install(キャッシュあり): 5秒
ディスク使用量
# 10個のプロジェクトで同じ依存関係を使用
npm: 5.0GB
yarn: 4.5GB
pnpm: 1.2GB
エディタの設定
VS Code
pnpmを使用するプロジェクトでは、VS Codeの設定を調整する必要はありません。ただし、TypeScriptプロジェクトの場合は、workspace版のTypeScriptを使用することを推奨します。
{
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true
}
WebStorm / IntelliJ IDEA
WebStormやIntelliJ IDEAでは、自動的にpnpmを検出します。手動で設定する場合:
- Settings → Languages & Frameworks → Node.js and NPM
- Package manager:
pnpmを選択
よくある質問
pnpmはnpmと完全に互換性があるか?
はい、pnpmはnpmと完全に互換性があります。package.jsonの形式も同じで、npmのscriptsもそのまま動作します。
既存プロジェクトをpnpmに移行すべきか?
以下の場合、pnpmへの移行を検討してください:
- ディスク容量を節約したい
- インストール速度を向上させたい
- モノレポを使用している
- 依存関係を厳格に管理したい
pnpmで問題が発生した場合は?
まず、node_modulesとロックファイルを削除して再インストールを試してください。それでも解決しない場合は、.npmrcでnode-linker=hoistedを設定してnpmと同じ構造を使用できます。