Claude Codeで依存関係管理を安全に回す実践ガイド
Claude Codeでnpm/pnpm/Yarnの更新、lockfile、脆弱性監査、更新PR、CI検証を安全に回す実践手順。
依存関係管理は「一括更新」ではなく運用設計
JavaScript/TypeScriptのプロジェクトでは、アプリ本体のコードよりも依存パッケージの変化のほうが速いことがあります。react、vite、eslint、typescript、テストライブラリ、UIライブラリ、SDK、ビルドツール。最初は数十個でも、半年後には直接・間接の依存が数百個になります。
ここでClaude Codeを使う価値は「何でも最新版にする」ことではありません。むしろ逆です。更新してよい範囲を決め、lockfileを守り、脆弱性を見落とさず、CIで壊れた更新を止めるための作業者として使います。
lockfileとは、実際にインストールされたパッケージの正確なバージョンと整合性情報を固定するファイルです。npmならpackage-lock.json、pnpmならpnpm-lock.yaml、Yarnならyarn.lockです。package.jsonが「この範囲で使いたい」という宣言なら、lockfileは「今回はこの実体を使った」という証拠です。
この記事では、Claude Codeに依存関係管理を任せるための現実的な手順をまとめます。npm/pnpm/Yarnの違い、lockfileの扱い、脆弱性監査、Renovate/Dependabotの更新PR、GitHub Actionsでの検証まで扱います。関連するCI全体の設計はClaude Code CI/CDセットアップ、pnpm workspaceの境界設計はClaude Codeとpnpm workspaceも合わせて読むとつながります。
全体像: Claude Codeに任せる範囲を分ける
依存関係管理は、次の5つに分けると事故が減ります。
flowchart LR
scan["現状確認\noutdated/audit"] --> plan["更新方針\npatch/minor/major"]
plan --> pr["更新PR\nRenovate/Dependabot"]
pr --> ci["CI検証\ninstall/test/build"]
ci --> review["Claude Codeレビュー\n差分とリスク"]
review --> merge["人間が判断\nmergeまたは差し戻し"]
Claude Codeには、最初からnpm install package@latestを実行させないほうが安全です。まず「どのlockfileを使っているか」「どのパッケージマネージャーか」「更新対象は本番依存か開発依存か」「CIで何を通すか」を調べてもらいます。
依頼文はこのくらい具体的にします。
claude -p "
Inspect dependency management in this repository. Do not edit files yet.
Report:
- package manager and lockfile
- outdated direct dependencies
- security audit command to run
- scripts that must pass after dependency updates
- risky major updates that should be handled one by one
Return file paths and exact commands.
"
初心者向けに言い換えると、Claude Codeには「更新作業」より先に「棚卸し」をしてもらいます。棚卸しとは、今どの道具を使っていて、何が古く、何を直すと危ないかを一覧にすることです。
npm/pnpm/Yarnの違いを表で押さえる
比較記事ではありませんが、ここを曖昧にするとCIが壊れます。依存関係管理では、パッケージマネージャーごとのlockfileとCIコマンドを固定してください。
| ツール | lockfile | CIで使う基本コマンド | 古い依存の確認 | 脆弱性監査 |
|---|---|---|---|---|
| npm | package-lock.json | npm ci | npm outdated | npm audit --audit-level=high |
| pnpm | pnpm-lock.yaml | pnpm install --frozen-lockfile | pnpm outdated --format table | pnpm audit --audit-level high |
| Yarn modern | yarn.lock | yarn install --immutable | yarn up -iまたはyarn up <pattern> | yarn npm audit --recursive --severity high |
npm公式ドキュメントでは、npm ciはCIやデプロイのような自動環境向けで、package.jsonとlockfileが一致しない場合にlockfileを更新せず失敗します。pnpm公式ドキュメントでも、CI環境ではlockfileが不整合ならインストールを失敗させる動きが基本です。Yarn公式ドキュメントでは、--immutableがlockfileを変更しようとした時点で失敗させるオプションとして説明されています。
この3つの考え方は同じです。CIではlockfileを勝手に直さない。更新PRでlockfileを変え、CIで「そのlockfileで再現できるか」を確認します。
コピペで使える依存関係検証script
次のscriptは、package.jsonのpackageManagerかlockfileからnpm/pnpm/Yarnを判定し、固定インストール、脆弱性監査、typecheck、test、buildを順に実行します。scripts/verify-deps.mjsとして置けば、WindowsでもLinux CIでも使えます。
#!/usr/bin/env node
import { existsSync, readFileSync } from "node:fs";
import { spawnSync } from "node:child_process";
function readPackageJson() {
return JSON.parse(readFileSync("package.json", "utf8"));
}
function detectPackageManager(pkg) {
const declared = pkg.packageManager || "";
if (declared.startsWith("pnpm@")) return "pnpm";
if (declared.startsWith("yarn@")) return "yarn";
if (declared.startsWith("npm@")) return "npm";
if (existsSync("pnpm-lock.yaml")) return "pnpm";
if (existsSync("yarn.lock")) return "yarn";
if (existsSync("package-lock.json")) return "npm";
throw new Error("No package manager or lockfile detected.");
}
function run(command, args) {
const label = [command, ...args].join(" ");
console.log(`\n$ ${label}`);
const result = spawnSync(command, args, {
stdio: "inherit",
shell: process.platform === "win32",
});
if (result.status !== 0) {
throw new Error(`Command failed: ${label}`);
}
}
const pkg = readPackageJson();
const manager = detectPackageManager(pkg);
const installCommands = {
npm: ["npm", ["ci"]],
pnpm: ["pnpm", ["install", "--frozen-lockfile"]],
yarn: ["yarn", ["install", "--immutable"]],
};
const auditCommands = {
npm: ["npm", ["audit", "--audit-level=high"]],
pnpm: ["pnpm", ["audit", "--audit-level", "high"]],
yarn: ["yarn", ["npm", "audit", "--recursive", "--severity", "high"]],
};
const scriptCommands = {
npm: (name) => ["npm", ["run", name]],
pnpm: (name) => ["pnpm", ["run", name]],
yarn: (name) => ["yarn", ["run", name]],
};
const requiredScripts = ["typecheck", "test", "build"];
run(...installCommands[manager]);
run(...auditCommands[manager]);
for (const name of requiredScripts) {
if (pkg.scripts?.[name]) {
run(...scriptCommands[manager](name));
} else {
console.log(`\n- skip ${name}: script not found`);
}
}
console.log(`\nDependency verification passed with ${manager}.`);
package.jsonには次のように入れます。
{
"scripts": {
"deps:verify": "node scripts/verify-deps.mjs"
}
}
ポイントは、更新用scriptではなく検証用scriptにしていることです。Claude CodeにもRenovateにもDependabotにも、最後は同じ検証を通させます。
ユースケース1: 小さなWebアプリのpatch/minor更新
個人開発や小さなSaaSでは、eslint、prettier、vite、vitest、typescriptのpatch/minor更新はまとめて処理したいことが多いです。ただし、まとめてよいのは「壊れてもテストで拾える範囲」です。
Claude Codeにはこう依頼します。
claude -p "
Prepare a dependency update plan for devDependencies only.
Use the current package manager.
Group patch and minor updates for lint/test/build tools.
Do not update major versions.
After changes, run npm run deps:verify or the equivalent command.
Return a summary of changed packages and any failing command.
"
ここで失敗しやすいのは、typescriptとeslint関連を雑に上げることです。型エラーやlint rule変更は、アプリの挙動ではなく開発体験を壊します。軽く見えますが、CIが突然赤くなります。Claude Codeには「devDependenciesだけ」「majorは禁止」「失敗したコマンド名を返す」と条件を付けます。
実務では、更新後に次も見ます。
npm outdated
npm run deps:verify
git diff -- package.json package-lock.json
pnpmなら次です。
pnpm outdated --format table
pnpm run deps:verify
git diff -- package.json pnpm-lock.yaml
Yarn modernなら次です。
yarn up -i
yarn run deps:verify
git diff -- package.json yarn.lock
ユースケース2: 脆弱性監査を更新PRにつなげる
脆弱性監査は、怖い言葉が出るので焦ってaudit fix --forceを打ちがちです。これは危険です。--forceはmajor更新を含む修正を入れることがあり、認証、決済、ルーティング、ビルド設定まで壊す可能性があります。
まずは監査結果をJSONで見ます。
npm audit --json
pnpm audit --json
yarn npm audit --recursive --json
Claude Codeへの依頼は、修正ではなく分類から始めます。
claude -p "
Analyze the audit output and classify vulnerabilities.
Do not run audit fix yet.
For each high or critical issue, report:
- package name
- direct or transitive dependency
- installed version and fixed version if available
- whether a lockfile-only update may be enough
- whether a major update is required
Then propose the smallest safe remediation.
"
直接依存とは、自分のpackage.jsonに書いているパッケージです。間接依存とは、そのパッケージがさらに使っているパッケージです。初心者はここを混同しやすいです。間接依存の脆弱性なら、lockfile更新や親パッケージのminor更新で直ることがあります。直接依存のmajor更新が必要なら、普通の機能PRと同じくらい丁寧に扱います。
ユースケース3: モノレポやworkspaceの依存境界を守る
pnpm workspaceやnpm workspacesでは、内部パッケージの依存関係が壊れると、更新PRの影響範囲が読めなくなります。たとえばpackages/uiがapps/webをimportし始めると、共有UIの更新がアプリ固有ロジックに引っ張られます。
Claude Codeには、更新前にpackage graphを見てもらいます。
claude -p "
Inspect this workspace before dependency updates.
Find:
- packages/* importing from apps/*
- internal dependencies not using workspace:*
- duplicated versions of react, typescript, eslint, or test tools
- scripts that should run with pnpm --filter
Do not edit files. Return findings with file paths.
"
この観点はClaude Codeモノレポ管理でも重要です。依存関係管理は、単に外部パッケージを上げる作業ではありません。内部パッケージの向きが正しいか、同じツールのバージョンが分裂していないか、CIが変更範囲を見ているかまで含みます。
Renovateで更新PRを作る
自動更新PRにはRenovateかDependabotを使います。Claude Codeは、設定生成とPRレビューで使うのが現実的です。Renovateは細かいルールを作りやすく、lockfile maintenanceやautomergeの条件も設定できます。
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:recommended"],
"dependencyDashboard": true,
"lockFileMaintenance": {
"enabled": true,
"schedule": ["before 5am on monday"],
"automerge": true
},
"packageRules": [
{
"description": "Automerge low-risk development tool updates",
"matchManagers": ["npm"],
"matchDepTypes": ["devDependencies"],
"matchUpdateTypes": ["patch", "minor"],
"automerge": true
},
{
"description": "Patch production dependencies only after CI passes",
"matchDepTypes": ["dependencies"],
"matchUpdateTypes": ["patch"],
"automerge": true
},
{
"description": "Major updates need a human review",
"matchUpdateTypes": ["major"],
"labels": ["dependency", "major-update"],
"automerge": false
}
]
}
Renovate公式ドキュメントでは、automergeはテストが通るのを待ってから動く仕組みとして説明されています。つまり、テストが薄いプロジェクトでautomergeだけ増やすと危険です。Claude Codeには、設定だけでなく「このrepoのテストでautomergeしてよい範囲はどこか」をレビューさせます。
Dependabotで最小構成を作る
GitHubだけで始めるならDependabotも十分です。npm ecosystemはNode系の依存更新に使い、github-actions ecosystemはActions自体の更新に使います。
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
time: "06:00"
open-pull-requests-limit: 5
groups:
dev-tooling:
dependency-type: "development"
update-types:
- "minor"
- "patch"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
GitHub公式ドキュメントでは、Dependabotの設定はversion: 2とupdatesを基本に、package-ecosystem、directory、schedule.intervalを指定します。GitHub Actions自体も更新対象に入れておくと、actions/checkoutやactions/setup-nodeが古いまま残るのを防げます。
CIで「更新できたつもり」を止める
更新PRで一番多い事故は、ローカルでは動いたがCIではlockfile不整合で落ちることです。次のGitHub Actionsは、scripts/verify-deps.mjsを中心にして、依存更新PRにも通常PRにも同じ確認をかけます。
name: dependency-check
on:
pull_request:
push:
branches: [main]
jobs:
verify-dependencies:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- name: Enable Corepack for pnpm or Yarn projects
run: corepack enable
- name: Verify lockfile, audit, tests, and build
run: node scripts/verify-deps.mjs
キャッシュを入れる場合は、npmならcache: npm、pnpmならcache: pnpm、Yarnならcache: yarnをactions/setup-nodeに追加します。ただし最初はキャッシュよりも再現性を優先してください。キャッシュのせいで古い状態が残ると、依存更新の原因調査が難しくなります。
よくある失敗例と落とし穴
1つ目は、npm installをCIで使う失敗です。npm installはlockfileを更新することがあります。CIではnpm ciを使い、lockfileがずれていたら失敗させます。
2つ目は、audit fix --forceをそのまま実行する失敗です。脆弱性は直るかもしれませんが、major更新でAPIが変わることがあります。まず監査結果を分類し、最小修正を選びます。
3つ目は、major更新をまとめる失敗です。react、vite、eslint、typescriptのmajorを同時に上げると、どれが原因で壊れたか分かりません。majorは1つずつ、PRも分けます。
4つ目は、lockfileだけの差分を軽く見る失敗です。lockfileには実際に入る依存の全体像が出ます。見慣れないregistry、急に増えた巨大な依存、integrityの変化はレビュー対象です。
5つ目は、開発依存と本番依存を同じ扱いにする失敗です。eslintのpatch更新と、認証SDKや決済SDKの更新はリスクが違います。RenovateやDependabotのgroupでも分けます。
6つ目は、多言語サイトやコンテンツサイトでCTA確認を忘れる失敗です。依存更新でビルド設定やMDX変換が変わると、記事ページ、広告枠、CTA、コードブロックの見え方が崩れることがあります。公開前の確認習慣はClaude Code検証レシートワークフローが参考になります。
Claude CodeでPRレビューする型
更新PRが来たら、Claude Codeには差分の説明だけでなく、リスクと検証結果を出させます。
claude -p "
Review this dependency update PR.
Focus on package.json, lockfile, CI config, and test output.
Report:
- packages updated, grouped by dependency/devDependency
- direct vs transitive changes
- any major updates or peer dependency changes
- commands that passed or failed
- manual checks needed before merge
Do not make changes unless there is a blocking issue.
"
「問題ありません」だけのレビューは役に立ちません。どのパッケージが直接依存で、どれが間接依存か。CIは何を通したか。手動で見るべき画面はあるか。そこまで出すと、人間がmerge判断しやすくなります。
公式リンクと内部リンク
一次情報として、npmはnpm ci、npm outdated、npm auditを確認してください。pnpmはpnpm install、pnpm outdated、pnpm audit、Yarnはyarn install、yarn npm audit、yarn upが基礎です。
Claude Code側はClaude Code CLI reference、Claude Code hooks、Claude Code memoryを参照します。更新PRの運用はDependabot options referenceとRenovate automergeが実務でよく使います。
このサイト内では、CIの組み方はClaude Code CI/CDセットアップ、セキュリティ観点はClaude Codeセキュリティ監査、チームの運用ルールはCLAUDE.mdベストプラクティスにつなげると読み進めやすいです。
マネタイズにつなげるCTA
依存関係管理は地味ですが、チームでClaude Codeを使うなら最初に標準化したほうがよい領域です。更新PR、CI、レビュー観点、CLAUDE.md、hooksを別々に決めると、後から運用が散らかります。
個人開発なら、まずProductsにあるテンプレートやガイドで、CLAUDE.md、レビューprompt、CI確認の型を手元に置いてください。チームで導入する場合は、実際のrepoを前提にClaude Code研修・相談で依存更新ルール、automerge範囲、脆弱性対応、PRレビューの証跡まで一緒に決めるのが現実的です。
この記事で紹介した内容を実際に試した結果
この記事の手順は、Node.js 22、npm、pnpm、Yarn modernを想定して確認しました。scripts/verify-deps.mjsの形にしておくと、Claude Codeに「最後にdeps:verifyを通して」と頼めるので、更新作業と検証作業が分離しやすくなります。特に効果が大きかったのは、major更新を自動化から外し、patch/minorの開発依存だけをCI通過後にautomerge候補へ寄せたことです。lockfile差分を毎回見る習慣を入れるだけでも、不要な大規模更新や脆弱性対応の焦りがかなり減りました。
無料PDF: Claude Code はじめてのチートシート
まずは無料PDFで基本コマンドと最初の使い方をまとめて確認してください。登録後はそのままテンプレート集や導入相談にも進めます。
スパムは送りません。登録情報は厳重に管理します。
Claude Codeを仕事で使える形にしませんか?
無料PDFで基礎を固めたあと、すぐ使えるテンプレート集で試し、必要なら業務自動化や導入相談まで進められます。
この記事を書いた人
Masa
Claude Codeの実務活用、導入設計、収益導線改善を検証しているエンジニア。10言語の技術メディアを運営中。
関連書籍・参考図書
この記事のテーマに関連する書籍を楽天ブックスで探せます。
※ 当サイトは楽天市場のアフィリエイトプログラムに参加しています。上記リンクから商品をご購入いただくと、運営者に紹介料が支払われる場合があります。
関連記事
Claude Code権限セーフティラダー: 初心者がallowを広げる順番
Claude Codeの権限をread-onlyからbuild、限定編集、deploy確認まで段階的に広げる安全な運用手順。
Claude Code Small PR Proof Pack: 小さなPRをレビュー可能にする証拠セット
Claude Codeの小さなPRに、差分・検証・公開URL・CTA・rollbackを添える実務チェックリスト。
Claude Codeのコミット前レビューゲート: 差分、テスト、CTAをまとめて止める型
Claude Codeでcommit前に差分をレビューする実践手順。build、公開URL、CTA、Gumroadリンク、未翻訳本文を検知します。