個人開発でアプリを数年運用していると、ある日突然「このコード、もう自分でも読めない」と感じる瞬間があります。新機能を追加しようとしてファイルを開いたら、コメントアウトが積み重なったコードと、どこから呼ばれているかわからない関数が並んでいた——そういう経験をされた方は少なくないと思います。
私もそういう状況に陥っていました。2つのアプリを掛け持ちで運用しながら新機能を追加し続けた結果、コードベースは「動いているが触れない」状態になっていました。テストを書こうにも、副作用だらけで手が出せありません。リファクタリングしようにも、どこを変えると何が壊れるかわからありません。
そこで2026年の初めから、Claude Code を本格的に使って技術的負債の削減に取り組みました。3ヶ月後、同じコードベースはずいぶん扱いやすくなりました。このエントリでは、具体的に何をどの順序でやったか、どの部分でClaudeが役に立ち、どこで限界を感じたかを記録として残しておきます。
技術的負債の「地図」を作る:まず現状を数値で把握する
リファクタリングで最初につまずくのは「どこから手をつければいいかわからない」という問題です。感覚では「全部悪い」と感じていても、優先順位なく始めると途中で疲弊します。
まず私がやったのは、Claude Code に「技術的負債の地図」を作らせることでした。具体的には次のプロンプトをプロジェクトルートで実行します。
claude "このリポジトリ全体を分析して、技術的負債を以下の観点で棚卸しし、Markdown形式のレポートを出力してください:
1. TODO/HACK/FIXME/XXX コメントの一覧と場所
2. 重複しているコードのパターン(50行以上の類似コード)
3. 関数の複雑度が高い箇所(条件分岐が5段以上のもの)
4. 依存関係が循環しているモジュール
5. テストカバレッジが0%のファイル(package.jsonやtest設定がある場合)
各項目に「影響範囲」と「修正難易度」の2軸で★1〜5の評価をつけてください"このコマンドを実行すると、Claude は数分かけてリポジトリ全体を走査し、かなり具体的なレポートを出力してくれます。私のケースでは:
- TODO/HACKコメント:47箇所(そのうち2年以上前のもの:23箇所)
- 明らかな重複コード:8パターン(約1,200行)
- 循環依存:3組のモジュール
- テストカバレッジ0%のファイル:全体の67%
という数字が出てきました。「感覚」では「かなり悪い」と思っていましたが、数字になると「循環依存が3つしかない」「重複は8パターンに集約されている」と認識が変わります。この「地図」があることで、感情的にならずに優先順位をつけられるようになりました。
優先順位のつけ方:「緊急度 × 影響範囲」マトリクスで判断する
地図ができたら次は「どこから手をつけるか」の判断です。ここで私が失敗しがちだったのは「気になるところ」から手をつけてしまうこと。コードが醜くて目につく場所よりも、実際に問題を引き起こしている場所を先に直すべきでした。
Claude に優先順位の整理を依頼する際のポイントは、ビジネス上の制約を一緒に渡すことです。
claude "先ほどの技術的負債レポートを参照して、優先順位を決める手伝いをしてください。
制約条件:
- 毎週1〜2日しかリファクタリングに使えない
- 現行機能を壊してはいけない(本番環境で動いています)
- 3ヶ月後に新機能Xを追加する予定があり、その周辺モジュールは必ず整理したい
上記を踏まえ、『今週やること』『今月やること』『3ヶ月以内にやること』の3段階で分類してください"こうすることで、「循環依存の解消は影響範囲が大きいので今月はやらない、まず重複コードの8パターンを今週と来週で片付ける」という具体的なプランが出てきます。
特に「新機能Xを追加する予定」という情報を渡すのが重要でした。Claudeはその文脈を元に、新機能の周辺モジュールを「先に整理しておくべき負債」として特定してくれたからです。
重複コードの削減:サブエージェントを使った安全なリファクタリング
優先順位の上位に来た「重複コードの削減」から着手しました。私のケースでは、APIレスポンスのエラーハンドリングが8つのファイルに微妙に異なる形で書かれていました。
ここで Claude Code のサブエージェント(--headless + worktree)を使うと、「本番コードを一切触らずに」リファクタリング案を試せます。
# worktreeを使って安全な実験環境を作る
git worktree add /tmp/refactor-api-errors -b refactor/api-error-handling
claude --headless "
作業ディレクトリ: /tmp/refactor-api-errors
タスク: 以下の8ファイルに散らばっているエラーハンドリングロジックを統合してください
対象ファイル: src/api/users.ts, src/api/products.ts, src/api/orders.ts, ...(略)
手順:
1. まず8ファイルのエラーハンドリングパターンを分析する
2. 共通化できる部分とできない部分を整理する
3. src/utils/apiErrorHandler.ts として共通モジュールを作成する
4. 8ファイルを新モジュールを使うように書き換える
5. TypeScriptの型エラーがないことを確認する
6. 変更のdiffを最後に出力する
"このアプローチの良いところは、mainブランチには一切手を触れないことです。worktreeで作業させ、結果のdiffを確認してから git merge するかどうかを自分で判断できます。
実際に試してみると、8パターンあった重複コードは1つの共通ユーティリティと、各ファイルに必要な薄いラッパーに整理されました。コード量は約340行から95行になりました。
ただし、Claudeが出力したコードをそのままマージするのは危険です。私は必ずdiffを確認し、型定義が正確かどうか、エラーメッセージが変わっていないかをチェックしてからマージしていました。
循環依存の解消:「なぜこうなったか」を理解してから直す
重複コードの次に取り組んだのが循環依存の解消です。これが一番難しく、1ヶ月近くかかりました。
循環依存の問題は、コードの問題というより「設計の問題」です。A モジュールが B を import し、B が A を import する構造になっているということは、最初の設計段階で責務の分離が不明確だったことを意味します。
ここでClaude Code に直接「直して」と依頼するのは危険でした。なぜなら、循環依存を解消するには関係するモジュールの「責務の再設計」が必要で、それはAIより人間が判断すべき領域だからです。
代わりに私がやったのは、Claude に「なぜこの循環依存が生まれたかを分析させる」ことでした。
claude "src/store/userStore.ts と src/components/UserProfile.tsx の間に循環依存があります。
なぜこうなったかを分析し、設計上の問題点を説明してください。
解決策として考えられるパターンを3つ示し、それぞれのメリット・デメリットも教えてください"出力された3つのパターン(イベントバス導入、Context分離、依存性注入)を読んで、自分でどれを採用するか判断しました。この「分析→選択→実装」の流れが、循環依存解消には最も効果的でした。
テストのない領域にテストを追加する:段階的アプローチ
テストカバレッジが0%だったファイルへのテスト追加は、すべてを一気にやろうとすると挫折します。私はClaude を使って「まずこのファイルの重要な処理だけテストする」という段階的アプローチを取りました。
claude "src/utils/priceCalculator.ts のテストを作成してください。
ただし、全てのケースをテストしようとしなくていいです。
このファイルの処理の中で、バグが起きると最もユーザーに影響が大きい関数を3つ特定し、
その3つに絞ったテストを vitest で書いてください"「全部テストしろ」ではなく「最も重要な3つだけ」という指示が効果的でした。完璧なカバレッジを目指すより、リスクの高い部分だけでも網羅することで、実際の品質向上につながりました。
3ヶ月の作業を通じて、テストカバレッジは0%→38%になりました。完璧ではありませんが、コア機能の主要パスはテストで保護されています。
成果の測定:3ヶ月後に変わった数字
3ヶ月間の取り組みを終えて、改めて最初に作った「地図」と同じ分析をClaude に実行してもらいました。結果:
| 指標 | 開始時 | 3ヶ月後 | 変化 |
|---|---|---|---|
| TODO/HACKコメント数 | 47 | 19 | -60% |
| 重複コードパターン | 8パターン | 2パターン | -75% |
| 循環依存 | 3組 | 0組 | -100% |
| テストカバレッジ | 0% | 38% | +38pt |
| 最大関数複雑度 | 18 | 7 | -61% |
数字だけ見ると「半減以上できた」と言えます。ただし体感として最も大きかった変化は数字ではなく、「新機能を追加するのが怖くなくなった」という感覚です。以前は新しいコードを書くたびに「壊れるかもしれない」という不安がありましたが、今はずいぶん楽になりました。
Claude Code を使った技術的負債管理で学んだこと
3ヶ月やってみて感じた重要な点をいくつか挙げておきます。
Claudeに「全部やって」と言わない:技術的負債の解消には設計判断が伴います。Claudeは「選択肢を提示する」「具体的な実装を試す」ことは得意ですが、「どの設計を採用するか」は人間が決める必要があります。
worktreeを使って本番リスクをゼロにする:サブエージェントで自動リファクタリングを試す際は、必ずworktreeを使って分離した環境で実験します。mainブランチへの影響ゼロで試行錯誤できる点が、Claude Codeを使う最大のメリットの一つです。
週1回の「健康診断」を続ける:最初に作った「地図」と同じ分析を週1回実行することで、負債が再び積み重なっていないかを監視できます。自動化できる部分はClaude Code のフックに組み込みました。
全部は終わらない、終わらせなくていい:技術的負債はゼロにはなりません。「動いているが触れない」状態から「触れるが完璧ではない」状態になれば、開発速度は確実に上がります。完璧を目指さず、継続的に少しずつ改善する習慣を作ることが最終的なゴールです。
次にやるべきことは、今回整理したコードに対して「継続的な品質監視」の仕組みをClaude Code のフックで自動化することです。PRのたびにClaudeが負債指標をチェックし、悪化傾向があればコメントを残してくれる仕組みを作ろうと考えています。