【2026年最新】Claude Codeでレガシーコード移行・大規模リファクタ

Claude Codeでレガシーコードの移行・大規模リファクタリングを安全に進める手順を解説。仕様の読み解き、テストで安全網を張ってから小さく刻む進め方、言語・フレームワーク移行のコツまで開発者向けに。

【2026年最新】Claude Codeでレガシーコード移行・大規模リファクタ

【2026年最新】Claude Codeでレガシーコード移行・大規模リファクタ実践ガイド

結論:レガシーコードのリファクタ・移行は「AIに一括で書き換えさせる」のではなく、Claude Codeに仕様を読み解かせ、テストで安全網を張ってから小さく刻んで進めるのが2026年6月時点での最適解です。

  • 要点1: まずPlan Modeで読むだけ・変更しないモードに入り、巨大コードの仕様と依存関係を把握する。探索はサブエージェントに任せてコンテキストを汚さない。
  • 要点2: 振る舞いを保証するテスト(特性テスト)を先に書き、各ステップでテストが緑のままであることを確認しながらリファクタする。
  • 要点3: 言語・フレームワーク移行はファイル単位で刻み、各差分ごとにテストとコミットを回す。検証なしの本番投入は禁じ手。

対象読者: レガシーコードの保守・移行を任されているエンジニア/テックリード/PM。今日できること: 手元の属人化したモジュール1つをPlan Modeで読み解き、特性テストを1本書くところまで。

「誰も全体像を把握していない10年もののコードベース」「コメントもテストもない巨大な関数」——こういうレガシーコードの移行を任されると、最初の数日は仕様の読み解きだけで溶けていきます。私自身、Claude Codeを使い始めた頃に一番効果を感じたのが、実はこの「読み解き」フェーズでした。新機能を書かせるより前に、既存のわけのわからないコードを理解する相棒として圧倒的に強い。

ただし、ここで一つ釘を刺しておきます。「このディレクトリ全部、最新のフレームワークに書き換えといて」と丸投げして、テストもせずに本番へ——これが一番やってはいけないパターンです。リファクタリングの大原則は「振る舞いを変えないこと」。AIが生成したそれらしいコードは、エッジケースを静かに壊していることがあります。Claude Code公式の最適化ガイドでも「実装がもっともらしく見えてもエッジケースを処理していない」という落とし穴(trust-then-verifyギャップ)が明記されています。本記事では、この罠を避けて安全に段取りを組む具体的な手順を、開発者視点で解説します。

レガシー移行を安全に進める4ステップ。①仕様把握(依存と副作用の洗い出し)→②テストで安全網(特性テストを先に作る)→③小さく刻む(テスト緑を維持)→④段階移行。一括書き換えで検証せず本番投入はNG。
レガシー移行を安全に進める4ステップ(仕様把握→テスト安全網→小さく刻む→段階移行)

そもそもなぜレガシー移行でClaude Codeが効くのか

レガシーコードの厄介さは、ほとんどが「情報の欠落」に由来します。仕様書がない、書いた人がいない、テストがない。つまりコードそのものが唯一の真実になっている状態です。Claude Codeはこの「コードを読んで意図を推論する」作業が得意で、ファイルを読み、コマンドを実行し、git履歴まで遡って「なぜこのAPIはこんな変な形になったのか」を要約させられます。

一方で、コードベースが大きくなるほど注意が必要です。Claude Code公式ドキュメントは「コードベースが大きくなると、小規模プロジェクト向けにチューニングされたデフォルト設定が、タスクと無関係な命令やファイル読み込みでコンテキストウィンドウを埋め、トークンを浪費してClaudeの性能を劣化させる」と明確に警告しています。LLMはコンテキストが埋まるほど性能が落ちる——これが全ての段取りの土台にある制約です。

だからこそレガシー移行では、「Claudeに何を読ませ、何を読ませないか」の設計が成否を分けます。後述するサブエージェントへの探索委譲、CLAUDE.mdの階層化、不要ディレクトリの読み込み除外は、すべてこのコンテキストを節約してClaudeを今いじっているコードに集中させるための道具立てです。

段取り全体像:レガシー移行を安全に進める6ステップ

個別のテクニックに入る前に、全体の流れを押さえておきます。順序を守ること自体が安全装置になります。

  1. 探索(Explore): Plan Modeに入り、対象モジュールの仕様・依存関係・副作用を把握する。変更はまだ一切しない。
  2. 安全網の構築: 現状の振る舞いを保証する特性テスト(characterization test)を先に書き、いまのコードで緑になることを確認する。
  3. 計画(Plan): リファクタ/移行の手順を細かいステップに分割した計画を作り、マークダウンファイルに保存する。
  4. 段階実装(Code): 計画に沿って1ステップずつ変更し、各ステップ後に必ずテストを走らせて緑を維持する。
  5. コミット: 緑になった単位で即コミット。差分を小さく保ち、いつでも戻れる状態にする。
  6. 独立レビュー: サブエージェントに差分だけを渡し、計画との乖離・スコープ外の変更・抜けたテストがないかを点検させる。

この流れは、Claude Code公式の「Explore first, then plan, then code(まず探索、次に計画、それから実装)」ワークフローを、テストファースト原則と組み合わせたものです。次章から各ステップを具体的なコマンド・指示例とともに見ていきます。

ステップ1:Plan Modeでレガシーコードを読み解く

レガシー移行の最初の一手は、絶対にコードを書かせないことです。Plan Modeは「Claudeがファイルを読んで計画を提案するが、承認するまで一切編集しない」モードで、まさに読み解きフェーズのためにあります。起動は次のいずれか。

claude --permission-mode plan

あるいはセッション中に Shift+Tab を押してトグルで切り替えられます。Plan Modeに入ったら、いきなり「リファクタして」ではなく、まず仕様を吐き出させます。

このモジュールの依存関係と副作用を洗い出して、現状の仕様書としてまとめて。
どの外部システムに依存し、どの状態を書き換えているかを明示して。

属人化した関数1つを理解したいときは、もっと焦点を絞ります。公式ガイドが挙げる「シニアエンジニアに聞くような質問」をそのまま投げるのが効きます。

このファイルの△△関数が、なぜ foo() ではなく bar() を呼んでいるのか
git履歴を遡って、このAPIがこの形になった経緯を要約して。
この関数が処理しているエッジケースを全部列挙して。

ここで重要なのは、読み解きの成果物(仕様書・依存関係図)をマークダウンファイルに書き出させておくことです。長い移行セッションでは途中でコンテキストが圧縮(compact)されますが、ファイルに保存した計画や仕様は会話履歴が消えても残ります。これは公式が「パッケージをまたぐ変更ではプランをファイルに保存せよ」と推奨している理由でもあります。

ステップ2:サブエージェントに探索を委譲してコンテキストを守る

巨大コードベースを読み解くと、Claudeは大量のファイルを読み込み、そのすべてがあなたのメインコンテキストを消費します。レガシー移行で何十ファイルも読ませると、肝心の実装フェーズに入る頃にはコンテキストがノイズだらけ——これが「infinite exploration(無限探索)」という典型的な失敗パターンです。

対策はシンプルで、探索をサブエージェントに丸ごと任せること。サブエージェントは独立したコンテキストウィンドウでファイルを読み、要約だけを返してきます。指示は明示的に出します。

サブエージェントを使って、この認証まわりがトークンリフレッシュを
どう扱っているか調査して。再利用できる既存ユーティリティがあれば併せて報告して。

公式ドキュメントは「コンテキストが根本的な制約である以上、サブエージェントは最も強力なツールの一つ」と位置づけています。レガシー移行では、たとえば「旧フレームワークの全使用箇所をリストアップする」「廃止予定APIを使っている箇所を洗い出す」といった広く浅い調査をサブエージェントに投げ、メインセッションは実装と判断に集中させる、という分担が効きます。

大規模コードベースでは、サブエージェントをgit worktreeで隔離する手もあります。各サブエージェントがフルツリーではなく軽量なチェックアウト(sparse checkout)で動くため、並列で別パッケージを調査・改修してもファイルが衝突しません。Claude Codeのサブエージェント並列活用については、Claude Codeのサブエージェントを並列実行して開発を加速する実践ガイドも併せて参照してください。

ステップ3:テストで安全網を張ってから刻む(特性テスト)

ここがレガシー移行で最も重要なステップです。振る舞いを変えないことを保証する仕組みがないリファクタは、ただの破壊行為になりかねません。

レガシーコードはテストがないことがほとんどなので、まず「現状の振る舞いをそのまま固定するテスト」——特性テスト(characterization test)——を書きます。これはコードの正しさを検証するのではなく、今この瞬間の挙動を記録して、リファクタ後に同じ挙動を保てているかを確かめるためのテストです。Claudeへの指示はこうなります。

この関数の現状の振る舞いを保つテストを先に作って。
正しいかどうかではなく、いまの入出力をそのまま固定する特性テストにして。
代表的な入力に加えて、境界値・異常系も網羅して。

テストを書かせたら、必ず「いまのコードで緑になること」を確認させます。リファクタ前に緑であって初めて、リファクタ後の赤が「壊した証拠」になるからです。公式の検証ガイドは「Claudeに検証手段(テスト・ビルド・スクリーンショット)を与えよ」と繰り返し説いており、テストがあるとClaudeは自分でループを閉じられます——変更し、テストを走らせ、結果を読み、緑になるまで自走する。

テストを書く際は、既存のテストスタイルに合わせさせるのがコツです。Claudeはプロジェクトの既存テストファイルを読み、使われているフレームワーク・アサーションパターンを踏襲します。指示の型は次の通り。

NotificationsService のうちテストでカバーされていない関数を特定して。
既存のテストの書き方(フレームワーク・命名規則)に合わせてテストを追加し、
追加したテストを実行して、失敗があれば直して。

テストファースト原則を組織のルールとして固定したいなら、CLAUDE.mdやサブエージェント定義に落とし込むのが有効です。プロジェクトのテスト規約やワークフローの明文化については、CLAUDE.mdによるプロジェクトメモリ設計ガイドが参考になります。

ステップ4:振る舞いを保ったまま段階的にリファクタする

安全網ができたら、いよいよリファクタです。鉄則は「小さく、テスト可能な単位で刻む」こと。Claude Code公式の共通ワークフロー集も、リファクタのコツとして「小さくテスト可能な増分で行う」「必要なら後方互換性を保つ」を明示しています。

公式が示すリファクタの基本レシピは、次の4段階です。これをそのまま指示の流れに使えます。

  1. 対象を特定する: 「コードベースから廃止予定APIの使用箇所を見つけて」と廃止予定・古い書き方を洗い出させる。
  2. 提案を出させる: 「utils.js をモダンな書き方にリファクタする方法を提案して」と、いきなり書き換えず方針を先に提示させる。
  3. 振る舞いを保って適用する: 「同じ振る舞いを維持したまま utils.js を最新仕様にリファクタして」と、必ず「振る舞いを維持」を明記して適用させる。
  4. 検証する: 「リファクタしたコードのテストを実行して」と、ステップ2で張った安全網で確認させる。

この「振る舞いを保つ」という一言をプロンプトに必ず入れるのが、レガシー移行での事故防止の肝です。実務では、1関数・1モジュール単位で上記サイクルを回し、テストが緑になったら即コミットします。差分を小さく保てば、もし途中で壊れても /rewind やチェックポイントで巻き戻して別アプローチを試せます。

もう一つの実践的な指示パターンが「症状ベースで頼む」こと。漠然と「直して」ではなく、症状・疑わしい場所・直った状態を一文で渡します。

セッションタイムアウト後にログインが失敗するという報告がある。
src/auth/ のトークンリフレッシュ周辺を確認して、
まず問題を再現する失敗テストを書いてから直して。

ステップ5:言語・フレームワーク移行をファイル単位でファンアウトする

「React→Vue」「Python 2→3」「旧フレームワーク→新フレームワーク」といった大規模移行は、1セッションで一気にやろうとすると必ずコンテキストが破綻します。ここでの定石はファイル単位で刻み、ファンアウト(fan-out)することです。

まずClaudeに移行対象ファイルの一覧を作らせます。

移行が必要な全ファイルをリストアップして files.txt に書き出して。
依存関係の浅いリーフモジュールから順に並べて。

そのうえで、非対話モード(claude -p)でファイルごとにClaudeを呼び出すループを組みます。各呼び出しが独立したコンテキストで動くため、コンテキスト汚染が起きません。

for file in $(cat files.txt); do
  claude -p "$file を React から Vue に移行して。テストを走らせ、緑なら OK、失敗なら FAIL だけ返して。" \
    --allowedTools "Edit,Bash(git commit *)"
done

ここでの実務上のコツは、いきなり全件流さず、最初の2〜3ファイルで試すこと。公式も「最初の数ファイルで何がうまくいかなかったかを見てプロンプトを磨いてから、全件に流せ」と推奨しています。--allowedTools で権限を絞っておくのは、無人実行時の安全装置として必須です。各ファイルの移行後にテストとコミットを回すことで、2,000ファイルあっても「どこまで移行済みか」が常にgit履歴で追えます。

移行を組織横断のルールやワークフローとして定着させる段階については、Claude Codeの法人導入・組織展開ガイドで、権限設計やチーム運用の観点を補えます。

ステップ6:大規模コードベースでClaudeを「迷子にさせない」設定

レガシー移行が長期戦になるほど、Claude Codeの設定面の作り込みが効いてきます。Claude Code公式の大規模コードベース向けガイドが挙げる、移行で特に効く設定を絞って紹介します。

  1. CLAUDE.mdを階層化する: ルートに全体の構造を、各パッケージ/サブシステムのディレクトリにそこ固有の規約を置く。Claudeは作業中のコードの規約だけを読み込み、無関係なサブシステムの命令でコンテキストを埋めない。
  2. 触らないコードのCLAUDE.mdを除外する: claudeMdExcludes 設定で、絶対に触らないレガシーパッケージやベンダーコードのCLAUDE.mdを読み込み対象から外す。
  3. 生成物・ベンダーコードの読み込みを禁止する: permissions.denyRead ルールを足し、dist/build/・生成コードをClaudeが開かないようにする。
  4. コードインテリジェンスを入れる: 言語サーバー連携プラグインを入れると、シンボルの定義元・参照箇所をファイル全走査ではなく「定義へ移動」で引けるようになり、読み込みコストが激減する。

除外設定は、たとえば次のように .claude/settings.local.json に書きます(個人設定にしたい場合)。

{
  "claudeMdExcludes": [
    "**/packages/legacy-*/**"
  ],
  "permissions": {
    "deny": [
      "Read(./**/dist/**)",
      "Read(./**/build/**)",
      "Read(./vendor/**)"
    ]
  }
}

こうした設定は「Claudeに何を見せないか」を制御するものです。CLAUDE.md自体の書き方(広く適用される規約だけを短く書く、肥大化させない)については、公式が「肥大化したCLAUDE.mdはClaudeが半分を無視する原因になる」と警告しています。各行について「これを消したらClaudeがミスするか?」と自問し、しないなら削るのが原則です。

やってはいけないパターンと正しいやり方

レガシー移行でやりがちな失敗を、❌/⭕の形で整理します。これだけは避けてください。

❌ パターン1:AIに一括で書き換えさせて検証せず本番投入
最も危険な禁じ手。もっともらしいコードが静かにエッジケースを壊します。
⭕ 正しいやり方: 特性テストで安全網を張り、各ステップでテストが緑のままであることを確認してから進める。検証できないものはshipしない。

❌ パターン2:1セッションで全部やろうとする(kitchen sink session)
読み解き・テスト・リファクタ・別モジュールの調査を全部同じ会話に詰め込むと、コンテキストがノイズだらけになりClaudeが earlier instructions を忘れ始めます。
⭕ 正しいやり方: 無関係なタスクの間は /clear でコンテキストをリセット。探索はサブエージェントに逃がす。

❌ パターン3:同じ間違いを何度も修正し続ける
Claudeがミスし、直し、まだミスし、また直す——失敗したアプローチでコンテキストが汚染されます。
⭕ 正しいやり方: 同じ問題を2回修正したら、いったん /clear して、学んだことを盛り込んだより具体的なプロンプトで仕切り直す。長い汚れたセッションより、クリーンなセッション+良いプロンプトのほうがほぼ常に勝ちます。

❌ パターン4:スコープを切らずに「調査して」と丸投げ
無限探索に陥り、数百ファイルを読んでコンテキストが埋まります。
⭕ 正しいやり方: 調査を狭くスコープするか、サブエージェントに任せてメインコンテキストを消費させない。

独立レビューで「壊していないこと」を担保する

移行が一段落したら、実装したのと同じセッションに「OK」と言わせて終わりにしないこと。自分が書いたコードを自分でレビューするとバイアスがかかります。公式が推奨するのは、新しいコンテキストのサブエージェントに差分だけを渡して点検させる「敵対的レビュー」ステップです。

サブエージェントを使って、このリファクタの差分を PLAN.md と照合してレビューして。
計画の各要件が実装されているか、列挙したエッジケースにテストがあるか、
タスクのスコープ外の変更が混ざっていないかを確認して。
スタイルの好みではなく、正しさと要件に影響する「抜け」だけを報告して。

サブエージェントは実装に至った推論を知らず、差分とあなたが与えた基準だけを見るので、結果を独立した目で評価できます。注意点として、「抜けを探せ」と指示されたレビュアーは、健全なコードでも何かしら報告しがちです。すべての指摘を潰すと過剰設計(不要な抽象化・防御的コード・起こり得ないケースのテスト)に走るので、正しさと要件に影響する指摘だけに絞らせるのがコツです。バグ検出の自動レビューなら、Claude Code同梱の /code-review スキルを使うと、新しいサブエージェントが差分のバグを点検して結果を返してくれます。

よくある質問(FAQ)

Q. テストが全くないレガシーコードでも、Plan Modeだけでリファクタを始めていい?
A. 始めてはいけません。テストがない状態でのリファクタは「振る舞いが変わっていないこと」を確認する術がありません。必ずステップ2の特性テストを先に書き、現状で緑にしてから着手してください。

Q. 大規模移行はファンアウトで全自動化できる?
A. 機械的なファイル単位の変換(インポート書き換え、構文変換など)は claude -p ループで自動化できますが、各ファイルでテストを走らせて緑/赤を判定させ、最初の数ファイルでプロンプトを磨いてから全件に流すのが前提です。検証なしの全自動投入は避けてください。

Q. コンテキストが途中で圧縮されて、移行の方針を忘れられそうで不安。
A. 計画・仕様・進捗をマークダウンファイルに書き出させておけば、会話が圧縮されてもファイルは残ります。長い移行セッションでは「計画をファイルに保存」が公式の推奨パターンです。

今日からできる3アクション

レガシー移行は、最初の一歩を小さく踏み出すのが続けるコツです。今日できることを3つ。

  1. 属人化したモジュールを1つ選び、Plan Modeで読み解く。 claude --permission-mode plan で起動し、依存関係と副作用を仕様書としてマークダウンに書き出させる。
  2. その振る舞いを固定する特性テストを1本書く。 「正しさではなく現状の入出力を固定して」と指示し、いまのコードで緑になることを確認する。
  3. 1関数だけ、振る舞いを保ってリファクタしてみる。 「同じ振る舞いを維持したまま」を明記し、テスト緑を確認したら即コミット。小さく刻む感覚を掴む。

次回は、移行後の新コードに対するレグレッションテスト戦略と、CI上で claude -p を使った継続的な品質ゲートの組み方を掘り下げる予定です。手元のレガシーコードで詰まったポイントがあれば、それ自体が次の記事の良いネタになります。


著者プロフィール

佐藤傑(さとう・すぐる)。株式会社Uravation代表取締役。X(@SuguruKun_ai)フォロワー約10万人。100社以上の企業向けAI研修・導入支援に携わる。著書『AIエージェント仕事術』(SBクリエイティブ)。SoftBank IT連載7回執筆。Claude Codeを使った実装・移行支援の現場知見をもとに執筆しています(2026年6月時点の情報)。

出典

関連記事(Claude Code 実践ガイド)

Next Step

この事例を、自社の業務に置き換える。

対象業務、利用データ、評価基準、社内展開の順番まで整理すると、Claude Code導入の失敗を減らせます。

導入を相談する