Claude Code のFable5でRemix2 -> React Router 7のマイグレーションさせてみた
この記事の操作
Fable 5 の発表ページを読んでいたら、おすすめユースケースにこんな記述がありました。
Software engineering. During early testing, Stripe reported that Fable 5 compressed months of engineering into days. In a 50-million-line Ruby codebase, the model performed a codebase-wide migration in a day that would otherwise have taken a whole team over two months by hand.
「移行タスクが得意」という主張です。ちょうど手元に Remix 2 で作った Cloudflare Pages アプリがあったので、React Router 7 への移行をやらせてみることにしました。
対象のアプリには Stripe(Checkout / webhook)・Clerk(認証)・動的 OGP 画像生成が入っており、それなりに複雑な状態です。
Fable 5 向けのプロンプトを作る
Fable 5 は従来モデルとプロンプトの作り方が異なるという記述が公式 Docs にあります。
Claude Fable 5 には Claude Opus 4.8 とは異なる動作上の特徴がいくつかあり、プロンプトやスキャフォールディングの更新が必要になる場合があります。
https://platform.claude.com/docs/ja/build-with-claude/prompt-engineering/prompting-claude-fable-5
個人開発で時間をかけすぎても仕方ないので、上記のページを Markdown でコピーして Fable 5 に丸投げしました。
claude fable 5への指示の出し方について教えて。
anthropicのdocsを添付する。
例えばremix2で作られたcloudflare pagesアプリがある。stripe / clerkなども入っており、OGP生成処理などややこしい状態だ。
これをreact router7に移行したりcloudflare workersへ移行したりすることを指示するには、それぞれどんなプロンプトを出すのが良いということなのか?
出てきたプロンプトがこれです。
## 背景と目的
このリポジトリは Remix 2 で構築した Cloudflare Pages アプリで、Stripe(Checkout / webhook)、
Clerk(認証)、動的 OGP 画像生成を含む。Remix 2 のメンテナンス終了に備え、
React Router 7 の framework mode へ移行したい。次フェーズで Cloudflare Workers への
移行も予定しているため、このフェーズでは挙動を変えずにフレームワークだけを差し替えることが目的。
## やること
Remix 2 から React Router 7 への移行を、移行完了の検証まで含めてエンドツーエンドで実施する。
## 境界(やらないこと)
- Stripe / Clerk / OGP 生成のロジックは、移行に必要な API 差分の吸収以外は変更しない
- 機能追加・抽象化の導入・移行と無関係なリファクタリング・依存パッケージの不要な更新はしない
- 後方互換 shim や feature flag は使わず、新 API に直接書き換える
## 検証
- ルートごとに移行したら、ビルドとローカル起動で該当ルートが動くことをツール実行結果で確認する
- 特に次の3点は実際に動かして確認する:(1) Clerk のログイン/保護ルート、
(2) Stripe webhook の受信と署名検証(stripe CLI の listen/trigger を使う)、
(3) OGP 画像エンドポイントが画像を返すこと
- 一定間隔で、別コンテキストの検証用サブエージェントに差分レビューをさせる
## 報告と中断のルール
- 進捗報告は、このセッションのツール実行結果で裏付けられる内容のみ。未検証なら未検証と明記する
- テストやビルドが失敗したら、出力を添えてそのまま報告する
- ユーザーに確認を取るのは「破壊的・不可逆な操作」「スコープの実質的変更」
「ユーザーしか持たない情報(環境変数の値など)が必要」の3つの場合のみ。それ以外は最後まで進める
## メモ
移行中に判明した Remix 2 と React Router 7 の API 差分や、Stripe/Clerk/OGP まわりで
ハマった点は MIGRATION_NOTES.md に1項目1教訓で記録する(次フェーズの Workers 移行で参照する)。
「境界(やらないこと)」「報告と中断のルール」をセットで渡しているのがポイントで、余計なところに手を出さないための制約と、どこまで自律で進めるかの裁量範囲を最初に明示しています。
Claude Code on the web に渡して実行
このプロンプトをそのまま Claude Code on the web に渡します。

インターフェース下部に「Fable 5 中」と表示されており、Fable 5 で動作していることが確認できます。あとは信じて待ちます。
ライブラリ差し替えから型チェックまで自動でこなす
最初に着手したのは依存パッケージの差し替えです。

@remix-run/{react,cloudflare,cloudflare-pages,dev} と @clerk/remix をまとめてアンインストールし、react-router@7.17.0 + @react-router/{dev,cloudflare,fs-routes} + @clerk/react-router をインストールしています。結果は「added 39 packages, removed 1 package, changed 13 packages」でした。
続けて vite.config.ts や react-router.config.ts、entry.client.tsx の編集に入りました。この時点でのトークン消費と経過時間がこちら。

開始から約 6 分、トークン消費は 2.2k でした。
Smoke Testからの不具合修正
ビルドを通したあと、ローカルサーバーを起動して各ルートの動作確認(Smoke test)まで進めていきます。

型チェック(27 件)が全通過し、ビルドも成功。サーバーを起動して curl でルートを一本ずつ叩いていきます。これはいわゆるSmoke test ですね。

トップやカテゴリページは 200 ですが、記事詳細ページが 500 になっています。自動的に原因特定に入り、8 コマンドで問題を切り分けていきます。

途中で OGP 画像エンドポイントを確認したところ、PNG(1200×630)が正常に返ってきたことを確認しています。500 は post 詳細ページのみに絞られました。この後も調査と修正がしばらく続きます。
30 分経過:Too many open files でスタック
移行前後のルートを比較するバックグラウンドタスクを動かしていたあたりで、こんなエラーが出てきました。

StripeやClerkなどのキーをClaude Code on the Web環境には提示していないため、「APIキーが原因だったら無視していいよ」と助け舟を出してみました。

ある程度割り切ることにしたのか、 ESLintでの作業にシフトし、赤文字の連続が一旦おさまりました。
57 分・96.9k tokens でひとまず完了、そのままセルフレビューへ

57 分 17 秒・96.9k トークン時点で、react-router dev(開発サーバー)が 200 で動作確認できたと報告が入りました。その後サブエージェントを利用してセルフレビューが始まります。
サブエージェントは git diff main...HEAD を全件読んで差分をレビューしていました。

そして出てきた重大指摘がこれです。

React Router 7 の single fetch モードでは、loader が返す Promise(旧 defer 相当)を streamTimeout が未設定だと約 5 秒で打ち切ります。このアプリには AI 検索機能(llmAnswer)があり、5 秒ではほぼ確実にタイムアウトします。サブエージェントがこれを発見して entry.server.tsx に export const streamTimeout = 60_000 を追加しました。
最終的な作業結果

最終的なサマリをまとめると以下のとおりです。
@remix-run/*→react-router@7.17.0+@react-router/{dev,cloudflare,fs-routes}へ差し替え。ルートファイルのリネームなし、flatRoutes()で既存の規約を継続json()/defer()を全廃。プレーンオブジェクト返却へ切り替え、404 はdata(..., {status:404})、webhook はResponse.json()(shim なし)entry.*はHydratedRouter/ServerRouterへ切り替え。AppLoadContext拡張はdeclare module 'react-router'へ- Clerk は v3 が
context.cloudflare.envへのアクセスを全書き換えするため、「挙動を変えない」方針を優先して v2.4.15(latest-v5 タグ)を採用。v3 化は Workers 移行フェーズで対応 - 子ルートが root loader を直接
.json()していた旧パターンをapp/utils/root-data.server.tsに切り出し、11 ルートを置換(API 差分の吸収として必要な唯一の構造変更)
スタックしていた箇所(未検証)

実鍵がないため検証できなかった項目は 2 つです。Clerk の実ログインフローと user.created webhook での Stripe 顧客作成。いずれも「ロジック自体は無変更」と明記されており、本番環境で確認するしかない部分です。
コンテキストウィンドウの消費量

コンテキストウィンドウ全体では 197.6k / 1.0M(20%)を消費しました。
案の定APIキーが関係する箇所で障害が発生
移行ブランチをデプロイしたところ問題が出たので、Cursor でデバッグ・復旧しました。困った時の Cursor composer-2.5。
Cursor が確認した障害の全容
サイト障害(HTTP 500)の原因として Cursor が特定したのは4件です。
@clerk/react-router: Missing publishableKeyが SSR 時に発生- Layout 内の
useRouteLoaderData('root')では RR7 で clerkState が取れない rootAuthLoaderが返す Response を JSON に展開していなかったgetAuth()が Cloudflare Workers 上で publishableKey を解決できなかった
修正ファイルは3つ。app/root.tsx(rootAuthLoader の Response JSON 化 + ClerkProvider を App コンポーネントへ移動)、app/utils/auth.ts(getAuth() に publishableKey を明示渡し)、robots[.]txt.tsx / llms[.]txt.tsx(import を react-router に変更)です。本番デプロイ後に HTTP 200 を確認しました。
まとめ
約 1 時間・197.6k トークンで Remix 2 → React Router 7 の移行がひとまず完了しました。APIキーなしの環境という制約の中で、ライブラリ差し替え・型チェック 27 件通過・ビルド・Smoke test・OGP エンドポイント確認まで自律でこなしています。
セルフレビューである程度不具合を検知していることもそうですが、APIキー関係の処理系統というモデルやエージェント自身にはどうにもできない要因部分以外では問題が起きなかったのもかなり印象的です。Claude Code on the Webではなく.envファイルのあるローカルPCでやればゼロ障害で完遂したのかもしれません。
前からやっておきたいと思いつつ手を出せていなかった領域だったので、今回のFable 5解放はちょうど良いタイミングでした。ただ、じゃあこれが Devin や Cursor Agent でも完遂できたのではないか?という点については個人的に気になるところもあり、ライブラリ移行系などはこれからもいろいろな切り口で試してみたいなと思います。
開発ノートをもっと読む
技術的な学びや実践的な開発ノートをもっと探索してみませんか?
⭐ この記事への反応
はてなアカウントでスターを付けることができます
関連記事
Claude Code の利用状況を OpenTelemetry で Grafana Cloud に流して手元で確認する
Claude Code を一日どれくらい使っているのか、トークンやコストを数字で見たくなりました。調べると OpenTelemetry(OTel)でメトリクスを出せると分かったので、Grafana Cloud に直接流し […]
KiroのProプランをFreeに戻した時の覚書
最近AIコーディング疲れを起こしている感じもあり、使用頻度の低いツールを解約したりダウングレードしています。今回はKiroをダウングレードしました。 Kiroのプラン変更はWebのダッシュボードから Kiroのプラン変更 […]
AI駆動開発でDevOps的な「小さなコミット・小さなリリース」に挑戦してみた(Devin編)
AI駆動開発でDevOpsの小さなコミット・リリースサイクルをDevinで実践。プロンプト設計から段階的な実装、CIチェック、マージまでの自律的な開発フローを検証し、効率的な開発プロセスを実現。
Claude Fable 5でサイトのレビューをしてみた
Claude Fable 5 が 6/23 以降はサブスクとは別課金になるという話が出ていたので、どう使うか少し考えました。 毎日のコーディングタスクよりも、ロードマップや方向性を決めるような「大きめの判断を要するタスク […]
