SYNON 記事 Cloudflare・インフラ

社内向けサービスの Cloudflare Workers 移行
プラットフォーム技術選定と移行計画

Workers + D1 + R2 に何を載せるか — 2026年8月時点の一次情報にもとづく判断

株式会社シノン 社内向けサービス群 / 現状:Next.js(App Router・Pages Router)、React SPA + Node API、その他が混在

作成日 2026-08-20 調査基準日 2026-08-20 対象:社内システム全般 関連:CloudFlare 移行プロジェクト

0結論(先に3行)

新規・移行の標準は「React SPA(Vite)+ Hono(Workers API)+ D1 / R2 / KV」 社内システムは Cloudflare Access の背後に置くため SSR が要らず、この構成が2026年8月時点で最も安定・最安・最も枯れている。すでに手元にある cf-internal-app-starter がまさにこの形で、方向性は正しい
TanStack Start は今回は採用しない 2025年9月の v1 RC 発表から11か月経った2026年8月20日現在も、公式ドキュメントに Release Candidate の警告バナーが出続けており、安定版の日程が公表されていない。加えて Cloudflare Vite plugin との併用で未解決の不具合(workers-sdk #13952、2026-05-18 起票・Open)が残っている。基幹寄りの社内システムを載せる根拠が弱い。2027年前半に再評価する。
既存 Next.js は「原則、SPA + API へ書き換え。書き換え不能なものだけ OpenNext で暫定退避」 Next.js を Workers に載せる基盤自体が2026年内に作り替わる(Next.js 16.2 の Deployment Adapters API 安定化 → OpenNext 各アダプタが移行予定 / Cloudflare 自身は vinext を実験中)。いま大量の Next.js を Workers に移すと、2027年にもう一度移行コストを払うことになる。
社内クライアント ブラウザ React SPA WARP 端末50台 Google Workspace SSO で認証 境界 Cloudflare Access 未認証は ここで止まる = SSR不要の根拠 1つの Worker Workers Static Assets React SPA を配信・課金対象外 Hono API /api/* Access JWT 検証 + 業務ロジック scheduled ハンドラ(夜間バッチ) ストレージ D1 業務データの正(SQLite互換) R2 添付・帳票(egress 無料) KV 設定・キャッシュのみ 業務データを KV に置かない
図1. 標準構成 — フロントは静的アセット、Worker が動くのは /api/* のときだけ

1前提の確認 — 2026年8月20日時点で確認できた事実

技術選定の前提が1年前の記事と大きく変わっている。まずここを揃える。以下はすべて2026年8月20日に一次情報で確認した値で、二次情報のブログ記事は採用していない。

1.1 フレームワーク側

項目事実(2026-08-20 時点)
Hono
安定
最新 v4.13.3(2026-08-18 公開)。v5 は未リリース。npm 週間ダウンロード 48,340,633(2026-08-12〜18、npm 公式 API 実測)。GitHub ★約31.7k。Cloudflare 公式フレームワークガイドに専用ページあり
TanStack Start
RC 継続
いまだ Release Candidate。公式 overview に「TanStack Start is currently in the Release Candidate stage!」のバナー継続。npm @tanstack/react-start の latest は 1.168.48(2026-08-19)だが、これは monorepo 共通の連番であり v1.0.0 到達を意味しない。安定版の日程は未公表(Discussion #5999 は2025年12月起票・いまだ未回答
React Router
v8 が現行
v7 ではなく v8 が現行。v8.0.0 が2026-06-17、v8.3.0 が2026-07-22。Node ≥22.22.0 / React ≥19.2.7 / Vite ≥7 が必須、CommonJS 廃止・ESM 専用react-router-dom パッケージ廃止、ミドルウェアが標準機能に昇格
Next.js最新 16.3.1 LTS(2026-08-13)。14 は EOL 済み15 は2026-10-21 に EOL 予定
@opennextjs/
cloudflare
最新 1.20.2。peerDeps は next: >=15.5.21 <16 || >=16.2.11Edge Runtime は未サポートexport const runtime = "edge" は削除必須)、Node Middleware(15.2〜)も未サポート
HonoX
alpha
依然 alpha(v0.1.61 / 2026-08-18)。README に「Breaking changes are introduced within the same major version」と明記
Remix 3
Beta
React Router に吸収されて終わり、ではなく React に依存しない別フレームワークとして再出発。2026-04-30 に Beta Preview 発表。Cloudflare Workers 向け公式ガイドは未確認

1.2 Cloudflare 側 — この1年で変わった点

項目事実
Cloudflare Vite plugin GAv1 系が GA(GA 告知 2025-04-08、npm の v1.0.0 は2025-04-04)。最新 1.52.1。workerd 上で Vite dev サーバーを動かし、HMR を保ったまま D1/R2/DO にアクセスできる。これが現在の Workers フロントエンド開発の中心
nodejs_compat が
デフォルト有効に
compatibility_date が 2026-08-04 以降の Worker では nodejs_compat / nodejs_compat_v2 が自動で有効。既存の明示指定は削除不要
Cloudflare Containers GA2026-04-13 に GA(Sandboxes と同時)。Workers Paid で利用可。lite / basic / standard-1〜4 のインスタンスタイプ
Workers VPC Betaまだ Beta(「Features and APIs may change before general availability」と明記)。AWS VPC 内リソースへの接続。ベータ期間中は無料
vinext 実験Cloudflare が2026-02-24 に発表した実験的プロジェクト。OpenNext のような「ビルド出力の変換」ではなく、Vite 上で Next.js の API 面を再実装する方式。カバー率94%、ただし 🚧 Experimental
Next.js Deployment
Adapters API
Next.js 16.2(2026年3月)で安定版に。OpenNext の各アダプタはこの統一 API へ移行予定で、リリースは2026年末見込み
Wranglerv4 系継続(最新 4.124.0)。v5 は未確認
ここが判断の分かれ目 Cloudflare は特定フレームワークを「推奨」と明示していない。フレームワークガイド一覧には React + Vite / Astro / React Router / Next.js / Vue / RedwoodSDK / TanStack Start / SvelteKit / Vike / Hono ほかがすべて対等に並んでいる。つまり「Cloudflare が推しているから」という選定理由は成り立たない。自分たちの要件で選ぶしかない。

2大前提:社内システムに SSR は要らない

技術選定で一番効いたのはこの一点なので、先に立てておく。

Next.js / TanStack Start / React Router v8 はいずれもサーバーサイドレンダリング(SSR)を中心に据えたメタフレームワークである。SSR が価値を持つのは主に次の3つのケースだ。

  1. SEO — 検索エンジンに HTML を読ませたい
  2. OGP / SNS シェア — クローラに初回 HTML を返したい
  3. 未認証ユーザーへの初回描画速度 — LCP を稼ぎたい公開ページ

社内向けサービスは、この3つがすべて該当しない。さらに決定的なのが、当社の社内システムはすでに Cloudflare Access(Zero Trust)+ WARP の背後に置く方針が確定していることだ(2026-08-17 に Google Workspace SSO で決定済み)。この構成では:

SSR メタフレームワーク構成 1つの Worker に全部入る フレームワーク + React SSR + ORM + 認証 + 業務ロジック gzip 後 10 MB 上限との戦いが常時発生 全リクエストで Worker 起動 → CPU 課金が発生 use client / use server / loader の境界を全員が理解し続ける フレームワークの破壊的変更が社内基幹を直撃 得られる価値:SEO・OGP・未認証LCP → いずれも社内では 0 SPA + API 分離構成 静的アセット React SPA Worker Hono API のみ 静的アセットは課金対象外・無制限・ストレージ料金なし Worker が動くのは /api/* のときだけ → CPU 課金が最小 Worker のバンドルは API だけ → 10 MB 上限に当たらない 境界は HTTP と型だけ → フレームワークの流行から切り離される 社内システムにおいて SPA + API は妥協ではなく最適解
図2. Access が前段にいる社内システムでは、SSR は価値ゼロでコストだけが残る
例外 採用サイト・製品LP・顧客向けポータルなど、社外に公開して SEO / OGP が要るものは別。そちらは §4.2 の判断で React Router v8 を使う。

3標準構成の定義

3.1 採用スタック

レイヤ採用理由
フロントReact + Vite + TypeScript(SPA)
React 19 / Vite 7
既存の React 資産をそのまま活かせる。SSR 境界の複雑さがない
配信Workers Static AssetsWorker に同梱でき API と同一オリジン。リクエスト課金なし・ストレージ課金なし。CORS も不要
開発@cloudflare/vite-plugin
1.52.x(GA)
開発時も本番と同じ workerd 上で動く。ローカルからバインディングにアクセスできる
APIHono 4.13.x週間 DL 4,830万、Cloudflare 公式ガイドあり、Workers ネイティブ。バンドルが極小
DBD1SQLite 互換。既存が SQLite なら移行コストが最小
ファイルR2egress 完全無料。添付ファイル・帳票 PDF
キャッシュ/設定KVマスタキャッシュ・機能フラグ。業務データの正には使わない
ORMDrizzle ORM 0.45.xCloudflare 公式ドキュメントに D1 接続手順あり。生成は drizzle-kit、適用は wrangler d1 migrationsmigrations_pattern の設定が必要)
入力検証Zod + @hono/zod-validator外部に API を公開するなら @hono/zod-openapi(1.6.1、v1 到達済み)
認証(境界)Cloudflare Access JWT
jose で検証
公式の専用 SDK は存在せず、jose による手動検証が2026年8月時点でも定石。@hono/cloudflare-access ミドルウェアも利用可
認可(アプリ内)D1 のロールテーブルAccess は「入れるか」まで。「何ができるか」はアプリの責務(§5.5)
テスト@cloudflare/vitest-pool-workers 0.21.xD1 / R2 / KV をテストファイル単位で分離してローカル実行できる
CI/CDGitHub Actions(主)
Workers Builds(小規模)
既存の deploy.yml 資産を活かす
監視Workers Logs + Logpush→R2 + SentryWorkers Logs の保持は有料でも7日。長期保全は Logpush 必須

3.2 採用しないもの(そして理由)

採用
Hono + React SPA

社内システムの標準。既存スターターの構成そのまま。

条件付き
React Router v8

SEO / OGP が必要な公開系のみ。v8 の ESM 専用化・Node 22 要件を見積もること。

暫定のみ
Next.js + OpenNext

書き換え不能な既存 Next.js の退避。2027年の再移行を計画に明記する。

2027年再評価
TanStack Start

RC が11か月継続。Vite plugin 併用の不具合が未解決。技術的な筋は良い。

不採用理由
TanStack Start① 2025-09 の RC から11か月、2026-08-20 現在も公式に RC バナー継続、安定版日程は未公表。② @cloudflare/vite-plugin と TanStack の Vite プラグインを併用すると SSR ランナーで __vite_ssr_import_11__.u is not a function が出る不具合(workers-sdk #13952、2026-05-18 起票・Open)。③ RSC は「v1 初期も experimental を継続」と公式が明言。④ RC 期間中に createStartHandler のシグネチャ変更で外部連携が壊れた実績。
受託開発の武器として個人・実験プロジェクトで習熟しておくことは推奨する。社内基幹に先に入れる理由が無い、というだけ。
HonoXv0.1.61、README に alpha と明記。社内基幹に載せる段階ではない
Next.js を新規標準に§4.3 参照。デプロイ基盤が2026年内に作り替わる
Remix 3React 非依存の別物。Beta。既存 React 資産と接続しない
PrismaWorkers のサイズ上限(有料 gzip 10 MB)との相性が構造的に悪く、D1 driver adapter の GA 明言も確認できなかった。Drizzle で足りる
Durable Objects を
業務データの正に
公式ガイダンス上、DO は「ユーザー単位/リアルタイム協調」向け。単一組織の申請ワークフローでは複雑性が増えるだけ
KV に業務データ結果整合。承認ステータスのような即時整合が要る値を置いてはいけない
Better Auth / Auth.jsAccess が前段にいる社内システムでは、パスワード管理・MFA・セッションを二重に持つ意味がない。@better-auth/cloudflare という公式パッケージは存在しない(コミュニティ製のみ)。社外公開アプリを作るときだけ再検討

4移行パス — 現状スタック別

現状 A. React SPA + Node API(Express等) B. Next.js(小〜中) App / Pages Router C. Next.js(大・期限あり) 書き換え不能 D. その他 Rails / PHP / ネイティブ依存 移行先と方式 A → 標準構成へ(最短ルート・最優先) API を Hono へ機械的に移植。req/res → c.req/c.json()。 フロントはそのまま Workers Static Assets へ。CORS が消える。 工数目安:小 B → 標準構成へ書き換え(画面単位で段階的に) app/api/**/route.ts は Web 標準なので Hono にほぼコピーで移る。 捨てるのは Server Component / Server Actions / ISR のみ。 工数目安:中(画面数に比例) C → OpenNext で暫定退避(恒久策にしない) Edge Runtime 削除・Node Middleware 不可・gzip 10MB 上限に注意。 2027年の再移行を最初から計画に書く(R5)。 D → Containers(GA)または EC2 据え置き + Tunnel 「全部 Workers に寄せる」を目的化しない。
図3. 現状スタック別の移行パス — A から着手し、C は暫定と明示する

4.1 Next.js(App Router / SSR)で作られた社内システム → 書き換え

方針:SPA + Hono API へ書き換える。ただし全面同時ではなく、画面単位で切る。

Next.js の要素移行先難度
app/**/page.tsx(クライアント寄り)React コンポーネント + TanStack Query
app/**/page.tsx(Server Component で DB 直叩き)Hono のルートハンドラ + fetch に分解
app/api/**/route.tsHono のルートへ移すRequest/Response ベースなのでロジックはほぼ流用可能
Server ActionsHono の POST エンドポイント + フォーム送信
next/image素の <img>(社内なら十分)または Cloudflare Images
middleware.ts(認証)不要になる — Cloudflare Access が前段で担う
next/link / useRouterReact Router をライブラリとして使う(framework mode ではない)
ISR / SSG社内システムでは通常不要。必要なら KV / R2 キャッシュ
最大の朗報 Route Handlers(app/api/**/route.ts)は Web 標準の Request/Response なので、Hono へほぼコピーで移る。社内システムの実装の大半はここに集まっているはずで、実際の書き換えは「画面のデータ取得を props 渡しから fetch に変える」ことが中心になる。

4.2 SEO / OGP が必要な公開系がある場合 → React Router v8

社内向けではないものが混じっていて SSR が要るなら、React Router v8 を選ぶ。TanStack Start ではない。

v8 の移行コストを必ず見積もる Node ≥22.22.0 / React ≥19.2.7 / Vite ≥7 が必須。CommonJS 廃止で ESM 専用react-router-dom パッケージ廃止。旧 @react-router/dev/vite/cloudflare(Cloudflare dev proxy)が廃止され Vite plugin への移行が必要。

さらに公式に明記された制約:「SPA mode and prerendering are not currently supported when using the Cloudflare Vite plugin」。SPA モードが要るなら React テンプレート + React Router をライブラリとして使う構成にする(=結局 §3.1 の標準構成に戻る)。

4.3 既存 Next.js が大きすぎて書き換えられない → OpenNext で暫定退避

「暫定」と明示した上で使う。恒久的な標準にはしない。理由は基盤が2026年内に作り替わるためだ。

2026-02 2026-03 2026-08(いま) 2026年末 2027 vinext 発表 Vite 上で Next.js を 再実装(実験) Next.js 16.2 Deployment Adapters API が安定版に OpenNext 1.20.2 従来方式(ビルド出力の リバースエンジニアリング) ← ここに載せると アダプタ移行 OpenNext が Adapters API へ(リリース見込み) やり方が別物に → 再移行コストが もう一度発生 いま大量の Next.js を Workers に移すと、2027年にもう一度移行コストを払う
図4. Next.js on Cloudflare の基盤再編タイムライン — C 分類は「2027年 再移行」を計画に書く

OpenNext を使う場合の実務上の必読事項

4.4 React SPA + Node API(Express / Fastify / NestJS)→ 最短ルート

フロントはそのまま Workers Static Assets へ、API を Hono に移すだけ。ここから着手する。

4.5 その他(Rails / PHP / Vue など)

「全部 Workers に寄せる」ことを目的化しない 移行の目的はコスト削減と運用の単純化であって、Workers 化そのものではない。EC2 + Tunnel + Access で十分に安全・安価に回る業務システムは、無理に動かさない判断が正解になる。

5プラットフォームの制約 — 事前に知っておくべきこと

すべて Cloudflare 公式ドキュメントの2026-08-20 時点の値。Free プランでは業務アプリは成立しないという結論が先に出るので、そこから読んでほしい。

5.1 D1

項目FreeWorkers Paid
DB 最大サイズ500 MB10 GB
アカウント合計ストレージ5 GB1 TB
アカウント最大 DB 数1050,000
Time Travel 保持7日30日
1 Worker 呼び出しあたりクエリ数501,000
行読み取り500万/日250億/月込み + $0.001/百万行
行書き込み10万/日5,000万/月込み + $1.00/百万行
ストレージ5 GB5 GB込み + $0.75/GB-月

共通の上限:テーブル最大100カラム、行 / BLOB 最大 2 MB、SQL 文最大 100,000 バイト、バインドパラメータ100個、クエリ最大実行時間30秒、1 Worker 呼び出しあたり同時接続6。

押さえるべき性質

既存 SQLite からの移行は最も楽なケース スキーマと INSERTwrangler d1 execute --file で流し込めば済むことが多い。ただし 1行 2 MB 上限BLOB を D1 に入れない(→ R2 へ)の2点だけは事前に洗うこと。

5.2 R2

$0.015
ストレージ /GB-月(低頻度 $0.01)
$4.50
Class A(書込系)/百万
$0.36
Class B(読取系)/百万
$0
egress(完全無料)
設計上の指示 — R2 にバージョニングは無い 添付ファイルの誤削除・誤上書きからの復旧はアプリ側で作る。実装方針は「物理削除しない(D1 のメタデータで論理削除)+ オブジェクトキーにバージョン ID を含めるreq/{id}/{uuid}/{filename})」。上書き保存という概念を作らない。この2点をテンプレートに強制する。

5.3 Workers 本体

項目FreePaid
CPU 時間10 ms既定30秒・limits.cpu_ms最大5分(300,000)
メモリ128 MB128 MB
Worker サイズ(gzip 後)3 MB10 MB
サブリクエスト50/req10,000/req
同時オープン接続66
静的アセット20,000ファイル100,000ファイル(1ファイル最大 25 MiB)
リクエスト10万/日1,000万/月込み + $0.30/百万
CPU 課金3,000万 ms/月込み + $0.02/百万 ms
Free プランでは業務アプリは成立しない CPU 10 ms は JSON を返すだけの API でも危うい。Workers Paid($5/月)は前提として稟議に載せること。なお Zero Trust の Free 50シートとは別課金である。
実務で一番効くのはメモリ 128 MB 帳票 PDF 生成、Excel 出力、画像処理はここに当たりやすい。回避策は ① ストリーミング処理(R2 へ逐次書き出し) ② Containers へ逃がす ③ クライアント側で生成する、の順で検討する。

なお HTTP リクエストの実行時間(Duration)自体に上限はない(クライアントが接続している限り継続可能)。上限があるのは CPU 時間の方。ただし Cron Trigger / Queue Consumer / DO Alarm は15分

5.4 Node.js 互換

compatibility_date2026-08-04 以降にすると nodejs_compat / nodejs_compat_v2 が自動有効になる。既存の明示指定は消さなくてよい。

対応度モジュール
フルサポートBuffer, Crypto, Events, HTTP/HTTPS, Net, Path, Process, Stream, String decoder, Timers, URL, Utilities, Web Crypto, Web Streams, Zlib
部分対応Console, DNS, Module, OS, Performance hooks, Test runner, TLS/SSL
スタブのみ(動かない)node:http2, node:vm, node:cluster ほか。ネイティブアドオン(sharp / node-canvas 等)も不可

5.5 認証と認可 — Cloudflare Access に「どこまで」寄せるか

当社はすでに Cloudflare Access + Google Workspace SSO で認証基盤を決めている(2026-08-17 決定)。アプリ側の設計はこれを前提にする。まずレイヤの分担を固定する。

到達制御 誰がアプリに届くか Cloudflare Access / Gateway Google Workspace SSO デバイス登録 グループポリシー = 境界 本人特定 誰からのリクエストか Access JWT を Worker で検証 jose で JWKS 検証 TEAM_DOMAIN + AUD 公式 SDK は存在しない 認可 何ができるか アプリ (D1 のロールテーブル) 承認者権限 部署別の閲覧範囲 金額上限 Access では担えない 監査 何をしたか D1 の監査ログ + Workers Logs Access のログは Free で 24時間しか残らない Workers Logs も有料で7日 → Logpush → R2 が必須
図5. 認証・認可のレイヤ分担 — Access は「入れるか」まで、「何ができるか」はアプリの責務

重要な実装上の注意

Cloudflare 公式の JWT 検証 SDK は存在しない2025-10-03 に「1クリック Access for Workers」が追加されたが、検証コード例は依然 jose ベース。既存スターターの src/worker/lib/access.ts の方針で正しい。Hono を使うなら @hono/cloudflare-access ミドルウェアも選択肢。
グループ情報が JWT に載っている前提で書かないグループを確実に取るなら /cdn-cgi/access/get-identity を叩く。ただし毎リクエストは重いので、アプリのロールは D1 に持ち、Access のグループは「初回プロビジョニング時の判定材料」として使う設計を推奨する。
Access は退職者を即座に締められないGoogle Workspace のアカウント停止だけでは Access セッションは切れず、JWT 有効期間中は通り続ける。アプリ側にも無効化フラグを持たせ、Access の Revoke と二重で締める。
サービス間認証(M2M)は Service TokensCF-Access-Client-Id / CF-Access-Client-Secret ヘッダー方式。なお名前の似た Cloudflare API の「Service Key authentication」は別物で、2026-03-19 に非推奨化・2026-09-30 に停止予定。混同しないこと。
アプリ独自の認証ライブラリは原則不要Access が前段にいる以上、パスワード管理・MFA・セッションを二重に持つ意味がない。@better-auth/cloudflare という公式パッケージは存在せず(コミュニティ製 better-auth-cloudflare のみ)、Auth.js は @auth/d1-adapter があるが、社内システムでは複雑性が増すだけ。社外公開アプリを作るときだけ再検討する。

5.6 テスト・CI/CD・監視

領域採用根拠・注意
ユニット/統合@cloudflare/vitest-pool-workers(0.21.x)Miniflare 上で D1/R2/KV をテストファイル単位で分離して実行できる。実質、Cloudflare 公式の主力テスト手段
E2EPlaywright(通常の test runner を CI から本番/プレビュー URL へ)@cloudflare/playwright は「Workers 上で動く Playwright」で用途が違う。混同しない
CI/CD(主)GitHub Actions既存資産(deploy.yml)があり、ビルド環境を自由に組める
CI/CD(小規模)Workers BuildsFree 3,000分/月・Paid 6,000分/月込み、超過 $0.005/分。ビルドタイムアウト20分。Durable Objects / Containers を持つ Worker には Preview URL が生成されないAPI トークンはユーザートークンのみという制約あり
プレビューPreview URLs + VersionsPR ごとに検証 URL。Preview URL にも Access を必ずかける
段階リリースGradual Deployments新バージョンに数%だけ流して様子を見る
ローカル開発Vite plugin + MiniflareD1/R2/KV はローカルエミュレート。Vectorize / Workers AI / Browser Rendering は remote: true が必要(既存スターターの設定は正しい)。DO / Workflows / 環境変数 / 静的アセット / Hyperdrive は remote: true 非対応でエラーになる
ログWorkers LogsFree 20万/日・保持3日/Paid 2,000万/月込み・保持7日、超過 $0.60/百万。単一ログ最大256 KB
ログ長期保全Logpush → R27日では監査に足りない。Phase 1 完了までに必ず稼働させる(移行の完了条件に含める)
APM@sentry/cloudflare(10.x)withSentry() でラップ。instrumentD1WithSentry で D1 計装、withMonitor で Cron 監視

6Workers に載らないものの逃げ道

状況逃げ道状態・コスト
ネイティブ依存(sharp / puppeteer / ImageMagick 等)、長時間バッチ、Rails / PHPCloudflare Containers GA2026-04-13 GA。lite(1/16 vCPU・256 MiB) 〜 standard-4(4 vCPU・12 GiB)。メモリ 25 GiB-h/月込み + $0.0000025/GiB秒、CPU 375 vCPU分/月込み + $0.000020/vCPU秒(アクティブ実行時間のみ課金)。Egress は北米/欧州 $0.025/GB(1TB/月無料枠)
既存 PostgreSQL / MySQL を残したいHyperdrive追加料金なし。接続プーリング + クエリキャッシュ。Free 10万クエリ/日、Paid 無制限。制約:キャッシュ応答最大50 MB、オリジン接続 Free約20 / Paid約100、クエリ最大60秒
AWS VPC 内のリソースに直接届きたいWorkers VPC Betaまだ Beta。ベータ期間中は無料。本番の前提にしない
そもそも動かない / 移行の費用対効果が薄いEC2 のまま + Tunnel + Accessすでに移行計画で決まっている構成。これで十分な業務システムは無理に動かさない

7移行計画とコスト試算

7.1 フェーズ

開始2週6週18週22週 Phase 0 基準の確定 標準化・棚卸し(2週) Phase 1 パイロット1本 最小の1本を完全移行(4週) Phase 2 横展開 A → B の順に順次移行(8〜12週) Phase 3 Next.js 群の判断 A/B/C/D 分類の確定(並行) Phase 4 旧環境撤去(4週)
図6. 移行フェーズ — Phase 1 のパイロット1本で詰まった点をテンプレートに還流させてから横展開する
Phase期間目安内容完了条件
0. 基準の確定2週標準スタックを社内標準として文書化。cf-internal-app-starter を「社内テンプレート」として整備(Drizzle 導入、Sentry 導入、Logpush 設定を追加)。移行対象システムの棚卸しと分類(§7.2)テンプレートから新規案件が立ち上がる状態
1. パイロット1本4週最も小さく・最も業務影響が少ないシステムを1本だけ完全移行。ここで詰まった点をテンプレートに還流する旧システムと並行稼働 → 2週間の実運用で問題なし
2. 横展開8〜12週分類ごとに順次移行。SPA + Node API のもの(A)から着手(最短ルート)各システムで並行稼働 → 切替
3. Next.js 群の判断Phase 2 と並行書き換え / OpenNext 暫定 / 据え置き の三分類を確定。OpenNext を選んだものは2027年の再移行を計画に明記分類表が承認されている
4. 旧環境の撤去4週EC2 上の該当プロセス停止、リソース削除、コスト確認切り戻し経路を1か月維持してから削除
Phase 1 のパイロット選定基準(この順で満たすものを選ぶ) ① 利用者が10名以下 / 業務停止しても半日は耐えられる ② データが SQLite または小規模 ③ 添付ファイルがある(R2 の運用を1回通しておきたい) ④ 承認フローがある(D1 のトランザクション設計を1回通しておきたい)

7.2 移行対象の分類表(Phase 0 で埋める)

#システム名現状スタック利用者DB添付分類移行方式優先度
1A/B/C/D
2
3
4
5

A:SPA + Node API

Hono へ API 移植のみ。最優先・最短。ここでチームが Workers に慣れる。

B:Next.js(小〜中)

SPA + Hono へ書き換え。Route Handlers はほぼコピーで移る。

C:Next.js(大・期限あり)

OpenNext で暫定退避。2027年の再移行を計画に明記する。

D:Workers に載らない

Containers または EC2 据え置き。無理に動かさない。

7.3 1システムあたりの標準手順

cf-internal-app-starter から新規リポジトリを作る
既存 DB のスキーマを migrations/0001_init.sql に写す(BLOB カラムは R2 へ分離、2 MB 超の行がないか確認
wrangler d1 execute DB --remote --file= で本番データを流し込む(先に staging で通す
既存 API を src/worker/routes/*.ts に移す(Express なら req/resc.req/c.json()
既存 React 画面を src/client/ に移す。データ取得を api.ts 経由に統一
Cloudflare Access のアプリケーションを作成し、AUD を wrangler.jsonc に設定
staging へデプロイ → 実データのコピーで検証
旧システムと並行稼働(旧を読み取り専用にし、期間を区切って切替)
本番切替 → 2週間は旧環境を停止せず残す
旧環境撤去

7.4 コスト試算

前提:社内システム3本、利用者100名、営業日20日/月、1人1日あたり API 300リクエスト。

項目使用量見込み込み枠追加費用
Workers リクエスト60万/月(静的アセットは課金対象外)1,000万/月$0
Workers CPU約600万 ms/月(平均10 ms/req 想定)3,000万 ms/月$0
D1 行読み取り約3,000万行/月250億/月$0
D1 行書き込み約3万行/月5,000万/月$0
D1 ストレージ〜1 GB5 GB$0
R2 ストレージ初年度 24 GB / 3年後 72 GB10 GB$0.21 → $0.93/月
R2 オペレーションClass A 数千/月100万/月$0
Workers Logs数百万イベント/月2,000万/月$0
Workers Paid 基本料$5/月
合計月 $5〜6(3年後でも $6程度)
$5〜6
Workers 化後の月額(社内3システム)
約 $40
EC2 t3.medium 単体の月額(東京・オンデマンド)
+ EBS / ALB
/ NAT / RDS
EC2 側にはさらにこれらが乗る
注意 — 効くのは Workers ではなく Zero Trust のシート この試算は Workers Paid($5/月・アカウント単位)のみを見ている。Cloudflare Access(Zero Trust)は現在 Free 50シートだが、利用者が51名を超えた時点で Pay-as-you-go 約 $7/user/月が発生する(移行計画書で既に指摘済みの最大の運用リスク)。社内システムを Workers に載せて便利になった結果、利用者が増えてシートを消費する、という順序に注意する。

8リスクと撤退基準

#リスク兆候対応・撤退基準
R1D1 が 10 GB 上限に近づく単一 DB が 6 GB 超古い年度データを R2 へアーカイブ。それでも足りなければ Hyperdrive + 外部 PostgreSQL へ。8 GB を超えたら即着手
R2メモリ 128 MB / CPU に当たる帳票生成でタイムアウト・OOM① ストリーミング化 ② Containers へ切り出し ③ クライアント生成。3回試して解決しなければ Containers に移す
R3Cloudflare の全面障害2025-11-18 に約6時間の全面障害(Access 認証もダッシュボードも不通)の実績業務停止許容度を業務ごとに事前に決める。「半日止まると業務が止まる」システム(給与・受発注・勤怠締め)は Workers 単独に載せない、または AWS 側にコールドスタンバイを残す
R4SLA もテクニカルサポートも無いWorkers Paid では有償サポートも別。基幹に載せる前にサポート契約の要否を経営判断として上げる
R5OpenNext 経由の Next.js が2027年に再移行を強いられるAdapters API への移行が2026年末Phase 3 で C 分類にしたシステムは「2027年 再移行」を最初から計画に書く。書かずに済ませると技術的負債として不可視化する
R6TanStack Start を待ってしまう「もうすぐ stable が出るはず」で着手が遅れる2027年3月時点で stable でなければ、以後の再評価をやめる。判断日を先にカレンダーに入れる
R7Access の JWT 検証を各アプリが独自実装して劣化するアプリごとに access.ts が微妙に違う検証ロジックは1本に固定し、テンプレート経由でしか配らない。既存スターターの CLAUDE.md の「ここは触らない」方針を全リポジトリで維持
R8R2 のバージョニング非対応による添付ファイル事故誤削除・誤上書きの報告物理削除を実装しない(D1 で論理削除)、オブジェクトキーに UUID を含める。この2点をテンプレートに強制
R9Workers Logs 7日で監査要件を満たせない監査・インシデント調査でログが無いPhase 1 完了までに Logpush → R2 を必ず稼働させる。これを移行の完了条件に含める

9Phase 0 チェックリスト

技術基準の確定

移行対象の棚卸し

費用と体制

判断日をカレンダーに入れる

10よくある反論への回答

「Hono は API フレームワークにすぎず、フルスタックのフレームワークではないのでは?」

その通りで、それが採用理由である。Hono はルーティング・データ取得・フォームといったフロント側の仕組みを持たない。社内システムでは、それらは React 側(React Router をライブラリとして + TanStack Query)で十分に賄える。フレームワークが持つ範囲が狭いほど、フレームワークの更新に振り回される面積が小さい。

一方で、Hono に DB プロビジョニング・分散トレーシング・バックグラウンドジョブといったインフラ機能を期待してはいけない。それらは Cloudflare のバインディング・Logpush・Cron / Queues が担う。

「Hono RPC(hc)で型を共有すれば最強では?」

小〜中規模では強力だが、大規模化すると型推論が TypeScript のコンパイル時間を直撃する

運用ルール 1システムあたり数十エンドポイントの社内システムなら RPC は有効。全社共通の巨大 API に育てる計画があるなら、Zod スキーマの共有に留めておく方が安全。

「TanStack Start は RC でも "feature-complete で API は stable" と公式が書いているのだから使えるのでは?」

公式の文言は「feature-complete かつ API は stable とみなす。ただしバグが無い・問題が無いという意味ではない」であり、後半が重要。実際に RC 期間中に createStartHandler のシグネチャ変更で外部連携が壊れており、Cloudflare Vite plugin との併用不具合も未解決のまま残っている。

受託開発の武器として個人・実験プロジェクトで習熟しておくことは推奨する。社内基幹に先に入れる理由が無い、というだけ。

「Next.js のままの方が採用・教育コストが低いのでは?」

Next.js の知識は無駄にならない。SPA + Hono へ移す場合、Route Handlers(app/api/**/route.ts)はほぼそのまま Hono に移り、React コンポーネントもそのまま使える。捨てるのは Server Component / Server Actions / ISR という「Next.js 固有のサーバー機構」であり、そこはそもそも Workers 上で完全には再現できていない部分でもある。むしろ「Workers に載っている Next.js が今どこまで動くのか」を追い続けるコストの方が高い。

「D1 ではなく既存の RDS を Hyperdrive で使い続ければよいのでは?」

既存 DB が PostgreSQL / MySQL で大きい場合はその通りで、Hyperdrive は追加料金なしの正しい選択肢。ただし今回は既存が SQLite / 小規模 DBと確認しているため、D1 への移行が最もコスト・運用ともに軽い。RDS を維持すると、Workers 化しても AWS 側の固定費(RDS インスタンス + NAT Gateway)が残り、コスト削減という移行目的の大半が失われる

11参考資料(一次情報)

Cloudflare 公式

フレームワーク公式

実運用の報告(判断根拠として参照したもの)

A付録:本書で「確認できなかった」こと

判断に影響しうるが、一次情報で裏が取れなかった項目をあえて明記しておく。この一覧を残しておくことが、次回の再評価の起点になる。

項目状況
TanStack Start の stable 予定日公式に一切の言及なし。Discussion #5999 は9か月間未回答
Next.js on Workers のコールドスタート・CPU 時間の実測値信頼できるベンチマークが見つからず。「サブミリ秒」等の主張はすべて第三者 SEO 記事の定性的表現で、数値の裏付けなし
Cloudflare がどのフレームワークを推奨しているか公式に推奨表示は存在しない(フレームワークガイド一覧はすべて対等)
D1 の TRIGGER 対応の可否公式ドキュメントに明示的記述を発見できず。使う前に staging で実地確認すること
D1 の書き込みが単一リージョンに限定されるかの公式明言read replication の仕組み上そう読めるが、断定する一次記述は特定できず
Prisma の D1 driver adapter が Preview から GA になったかの明言確認できず(Drizzle を採用するため実害なし)
Remix 3 の Cloudflare Workers 対応公式ガイド類は未発見