pnpm のモノレポで Claude Code を使い始めて最初に困るのは、たぶん「なぜか別パッケージのファイルまで触られる」ことではないでしょうか。apps/web の修正を頼んだのに、いつの間にか packages/ui の型定義まで書き換わっている — そんな経験は意外と多くの方がしているはずです。
私もこの問題に何度かやられて、結局のところ pnpm --filter と pnpm dlx の使い分けを Claude Code 側に明示的に教える必要があると気づきました。今回は、この組み合わせを実際にどう設定して、どう運用していくかを順を追って書いていきます。
pnpm --filter で作業範囲をきっちり絞る
pnpm の --filter は、特定のワークスペースに対してだけコマンドを実行するためのフラグです。Claude Code から呼ぶときも考え方は同じで、「このパッケージのことだけお願いします」という意思表示に使います。普段ターミナルで叩いている人にとっては当たり前の話ですが、Claude Code に意図を伝える「言語」として再認識すると効果が変わってきます。
# apps/web のテストだけ実行
pnpm --filter @myorg/web test
# packages/ui に依存しているパッケージ全部にテスト
pnpm --filter ...@myorg/ui test
# apps 配下のすべてに型チェック
pnpm --filter "./apps/**" typecheckポイントは ...@myorg/ui のように ... を前置すると「依存している側」を、@myorg/ui... のように後置すると「依存先」を辿れることです。Claude Code に「packages/ui を変更したら影響を受けるすべてのパッケージのテストを実行してください」と頼むときは、pnpm --filter ...@myorg/ui test を CLAUDE.md か CLAUDE.local.md に書いておくと話が早く進みます。日本語で「依存元」「依存先」と書いてもよいのですが、コマンド構文そのものを見せたほうが Claude Code の解釈ブレが少なくなる印象です。
pnpm dlx の落とし穴 — CI と挙動がずれる瞬間
pnpm dlx は npm の npx と同じく、ローカルにインストールせずにパッケージを実行できる便利な仕組みです。ただし Claude Code から呼ぶときは、いくつか気をつけたい点があります。
# 一見、便利
pnpm dlx prettier --write "src/**/*.ts"これを Claude Code に毎回叩かせると、CI と挙動がずれることが起きます。理由は dlx が 最新版を取りに行く ためで、ロックファイルに固定された prettier のバージョンとは違う結果が返ってくる可能性があるからです。フォーマット差分でレビューが荒れたり、CI だけ落ちたりしたときに、原因がここだと気づくまでに少し時間がかかります。
私は次のルールに落ち着きました。
- 使い捨てツール(一回だけ叩く CLI) →
pnpm dlxで OK。例えばpnpm dlx degitのようにテンプレート展開で一度しか走らないものです - コードベースに影響するツール(フォーマッター、リンター、ジェネレーター) → 必ず devDependencies に入れて
pnpm --filter <pkg> exec <tool>で実行する
CLAUDE.md には「prettier や eslint、typescript は dlx を使わず、各ワークスペースの node_modules の実体を呼ぶこと」と一行書いておきます。これだけで Claude Code の判断ブレがかなり減りました。
.claude/settings.json で運用ルールを固定する
Claude Code のツール権限カスタムポリシーを使うと、「pnpm 関連のコマンドだけ承認なしで実行可」のような設定ができます。モノレポではこれを上手く使うと、確認回数が劇的に減ります。
{
"permissions": {
"allow": [
"Bash(pnpm --filter *:*)",
"Bash(pnpm install:*)",
"Bash(pnpm test:*)",
"Bash(pnpm dlx:*)"
],
"deny": [
"Bash(pnpm publish:*)",
"Bash(pnpm -r publish:*)"
]
}
}deny に pnpm publish を入れているのは、誤って npm レジストリに勝手に公開されないための防御線です。私はこれで一度も事故を起こしていませんが、設定する前にローカルのリリース手順と矛盾しないかは確認してください。リリース作業を Claude Code に任せている方は、ここを allow 側に外すよりも、別途リリース用のセッションで --dangerously-skip-permissions を使うほうが事故が少ない気がします。
CLAUDE.md と CLAUDE.local.md の役割分担
モノレポでもう一つ整理しておきたいのが、ルートの CLAUDE.md と各パッケージの CLAUDE.local.md の使い分けです。私は次のように分けています。
- ルートの CLAUDE.md — 全パッケージ共通の規約。pnpm のフィルター構文、commit メッセージのフォーマット、リリース手順の禁止事項
- 各パッケージの CLAUDE.local.md — そのパッケージ固有の事情。例えば
packages/uiなら「Storybook を必ず更新する」「Tailwind の独自プリセットを使う」など
ルートに何でも書こうとすると CLAUDE.md が肥大化して、Claude Code の文脈を圧迫します。逆に各パッケージに分散しすぎると、共通ルールがあちこちにコピペされて保守が大変になります。「3 ヶ所以上で同じことを書いていたらルートに上げる」をしきい値にすると、ちょうどよいバランスに落ち着きました。
共有パッケージ修正からテストまでを一筆書きで
ここまでの組み合わせで何ができるかを、実際のシナリオで示します。packages/ui のボタンコンポーネントに新しい variant を追加するケースです。
# 1. 該当ワークスペースに直接ジャンプ
cd packages/ui
# 2. Claude Code に編集してもらう(エディタ内で完結)
# 3. 影響範囲のテストを一発実行(依存している側を全部)
pnpm --filter ...@myorg/ui test
# 4. ビルドが通るかも一気に確認
pnpm --filter ...@myorg/ui buildClaude Code には「このコンポーネントを変更したら、依存している apps/web と apps/admin のテストも走らせてください」と日本語で伝えるだけで構いません。CLAUDE.md に --filter ... の構文を書いておけば、自然とその構文を使ってテストまで回してくれるようになります。
さらに大規模なリポジトリで運用するなら、Claude Code の monorepo / Turborepo 統合ガイド と組み合わせるとキャッシュも効かせられます。CI の待ち時間が短くなるのはもちろん、ローカルでの繰り返しも軽くなります。コードベースが本格的に大きくなってきたら、Claude Code の大規模コードベース運用 も合わせて読んでおくと、より深いレベルでチューニングしていけるはずです。
次の一手
まずは .claude/settings.json に上記の permissions をコピペするところから始めてみてください。設定そのものは 5 分で済み、次に Claude Code を起動した瞬間から「pnpm 系コマンドの確認ダイアログ」がかなり減ります。1 セッションあたり数十回の "Allow?" を節約できる感覚があり、思考を切らさずに作業できる時間が増えるはずです。
その上で、自分のリポジトリでよく叩くコマンドパターンを CLAUDE.md に 3〜5 行追記すれば、Claude Code は「pnpm モノレポを理解しているメンバー」として動いてくれるようになります。--filter の挙動を頭の中で正しくモデル化するのに、私自身も助けられた一冊です。