Next.js を Cloudflare Workers で動かすなら、2026 年 10 月時点の答えは「新規は vinext、既存の OpenNext アプリで互換性の穴があるなら OpenNext を続ける」です。Cloudflare の公式ガイドは vinext を Next.js on Workers の既定の方法として案内しており1、OpenNext のガイドは「既存アプリの保守向け」と位置付けを変えました2。この記事では、2 つの違いと選び方を公式情報で整理し、Next.js 16 のアプリを実際に両方でビルド・プレビューした手順と、Claude Code に移行を任せる方法をまとめます。
Next.js を Workers で動かす方法は、vinext と OpenNext(@opennextjs/cloudflare)の 2 つです。どちらも最後は「1 つの Worker +静的アセット」になりますが、Next.js 本体でビルドするかどうかが違います。
- vinext: Cloudflare が開発する Vite プラグインです。Next.js の API(ルーティング、
next/* モジュール、サーバーレンダリング)を Vite の上に作り直しています。next build の出力は使いません3
- OpenNext:
next build の出力を、Workers で動く形に変換するアダプターです。Next.js 自身の出力を使うので、細かい機能まで動きやすいのが強みです4
vinext は vite build で直接 Worker 用の出力を作り、OpenNext は next build の出力を opennextjs-cloudflare build で変換する流れの比較図図: 筆者作成(Cloudflare 公式ドキュメント・vinext の README をもとに整理)
vinext の README は、OpenNext について「より成熟していて、Next.js の API をより広くカバーする。安全で実績のある選択肢が欲しいならそちらから」とはっきり書いています3。一方、Cloudflare のドキュメントは 2026-08-25 の更新で vinext を既定にしました1。この 2 つは矛盾しません。互換性の幅を取るか、ビルドの軽さと Workers との一体感を取るかの選択です。
2026 年 9 月に、選び方を左右する発表が 2 つ続きました。
- vinext 1.0 の公開(2026-09-28): Cloudflare は vinext を「AI の実験」から本番向けのフレームワークに引き上げたと発表しました。App Router・Pages Router・その混在、RSC、Server Actions、ISR、キャッシュの事前ウォームなどに対応しています5。npm でも
vinext@1.0.0 が 2026-09-28 に公開され、10 月 5 日時点の最新は 1.0.1 です
- Worker のサイズ上限が 64 MiB に(2026-09-04): 以前は圧縮後のサイズで Free 3 MB・Paid 10 MB の上限があり、Next.js アプリはこれに引っかかりやすい代表例でした。現在は圧縮後の上限がなくなり、非圧縮で 64 MiB(Free・Paid 共通)だけを見ます67
検索の動きも見ておきます。Google トレンド(日本・過去 90 日、2026-10-05 取得)の相対値では、「Next.js」は直近 4 週の平均が 1.3 で、その前の 8 週の平均 2.3 より下がっています。一方で「Cloudflare Workers」は 0.8 から 2.0 に、「Hono」は 0.8 から 2.7 に上がっています。どれも値は小さい語です8。Next.js そのものより、どこで動かすかに関心が移っていると読めます。
Google トレンドの相対値(日本・過去 90 日、直近 4 週平均と前 8 週平均)データを表で見る
Google トレンドの相対値(日本・過去 90 日、直近 4 週平均と前 8 週平均)| 語 | 前 8 週 | 直近 4 週 |
|---|
| Next.js | 2.3 | 1.3 |
|---|
| Cloudflare Workers | 0.8 | 2 |
|---|
| Hono | 0.8 | 2.7 |
|---|
出典: Google トレンド(日本・過去 90 日、2026-10-05 取得)の相対値。複数回の取得(Cloudflare Workers は別の回)。どの回も GitHub Copilot の直近 4 週は 26.7 で同じ尺度
関連キーワードの急上昇には「next js」(+250%)と「astro」(+110%)が出ていました8。フレームワーク選びと置き場所選びを同時に考える人が増えている、と見てよさそうです。
結論から言うと、Next.js 16 で新しく作るなら vinext、Next.js 14・15 や vinext 未対応の機能に頼るなら OpenNext です。違いを表にまとめます(2026 年 10 月時点)。
| 観点 | vinext | OpenNext(@opennextjs/cloudflare) |
|---|
| 仕組み | Vite の上で Next.js の API を再実装3 | next build の出力を Workers 用に変換4 |
| 対象の Next.js | 16.x のみ(古い API は非対応)3 | 16 の全マイナー、14・15 の最新マイナー4 |
| Cloudflare の位置付け | 新規アプリの既定1 | 既存アプリの保守向け2 |
| 開発サーバー | vite dev(workerd 上で実行) | next dev(Node.js) |
| バインディング | import { env } from "cloudflare:workers" | getCloudflareContext()(@opennextjs/cloudflare) |
| 設定ファイル | vite.config.ts と cloudflare.config.ts | wrangler.jsonc と open-next.config.ts |
| 未対応・部分対応 | Cache Components と PPR の一部、ビルド時の画像最適化など3 | Next.js 15.2 の Node.js ミドルウェア2 |
vinext の README は「Next.js 16 の API の約 94% に完全または部分的に対応」と書いています3。1.0 の発表では、重要な機能のテスト互換率が 99% を超えたとしています5。逆に言えば、全部ではありません。移行前に必ず vinext check を流します。
ビルドの速さとバンドルの小ささは vinext の売りです。2026-02-24 の発表時のベンチマーク(33 ルートの App Router アプリ、静的な事前レンダリングを止めた条件)を載せます9。
本番ビルド時間(33 ルートの App Router アプリ、秒)データを表で見る
本番ビルド時間(33 ルートの App Router アプリ、秒)| ツール | ビルド時間(秒) |
|---|
| Next.js 16.1.6(Turbopack) | 7.38 |
|---|
| vinext(Vite 7 / Rollup) | 4.64 |
|---|
| vinext(Vite 8 / Rolldown) | 1.67 |
|---|
出典: Cloudflare Blog「How we rebuilt Next.js with AI in one week」(2026-02-24)のベンチマーク
同じ発表では、クライアントバンドル(gzip 後)が Next.js 16.1.6 の 168.9 KB に対し、vinext(Rolldown)は 72.9 KB でした9。README は「初期の結果で、目安として見てほしい」と注意しています3。
既存の Next.js アプリなら、vinext check → vinext init → build:vinext → @vinext/cloudflare deploy の 4 段階です1。筆者が 2026-10-05 に、create-next-app(Next.js 16.3.8、App Router、Tailwind)で作ったアプリに API ルートを 1 つ足して試した結果を載せます。
vinext check で 100% 互換と出て、vinext init、build:vinext、start:vinext のあと curl で API ルートが JSON を返すまでのターミナル操作筆者が macOS(Node.js 24.6.0)で実行した出力を抜粋し、一部の行を 1 行にまとめて再生
npx vinext check
使っている next/* の import、ライブラリ、ルーターの種類を調べ、点数を出します。今回のアプリでは next/font/google と next/image が対応済みで、「100% compatible(7 supported, 0 partial, 0 issues)」でした。
npx vinext init --platform=cloudflare \
--cdn-cache=none --data-cache=none --image-optimization=none
対話なしで流すと、キャッシュと画像最適化の選択を求めるエラーで止まります。上のようにフラグで明示してください。--cdn-cache には response-store(推奨)・workers-cache・static-assets・data-cache も選べます。
init が行うことは次のとおりです3。
vinext・@vinext/cloudflare・vite・Cloudflare Vite プラグイン(v2 beta)・cf を追加する
package.json に "type": "module" と dev:vinext などのスクリプトを足す
vite.config.ts と cloudflare.config.ts を作る
既存の next dev はそのまま動きます。 next.config・tsconfig.json・ソースコードは書き換えません3。生成された設定は次の 2 つでした。
import { defineConfig } from "vite";
import vinext from "vinext";
import { cloudflare } from "@cloudflare/vite-plugin";
export default defineConfig({
plugins: [
vinext(),
cloudflare({
viteEnvironment: { name: "rsc", childEnvironments: ["ssr"] },
}),
],
});
import { bindings, defineConfig, defineWorker } from "cf/config";
export default defineConfig({
worker: defineWorker({
name: "my-next-app",
entrypoint: "vinext/server/fetch-handler",
compatibilityDate: "2026-09-28",
compatibilityFlags: ["nodejs_compat"],
assets: { notFoundHandling: "none" },
env: { ASSETS: bindings.assets() },
}),
});
cloudflare.config.ts は、Cloudflare の新しい CLI である cf(2026 年 10 月時点で 1.0.0-beta.12)の設定ファイルです。Wrangler の設定を使い続けたい場合は --legacy-wrangler-cloudflare-init を付けます3。
npm run build:vinext
Vite 8 が RSC・SSR・クライアントの各環境を順にビルドし、ルートの一覧を出します。筆者の環境(Intel Core i7・8 スレッド)では、npm の起動を含めて約 20 秒でした。比較のために同じアプリを OpenNext でビルドすると、next build を含めて約 44 秒でした。どちらも 1 回だけの計測です。また、OpenNext 側は静的ページの事前レンダリングもしているので、同じ条件の比較ではありません。
npm run start:vinext
curl -s localhost:4173/api/hello
start:vinext の中身は vite preview です。Cloudflare Vite プラグインが本番と同じランタイム(workerd)でビルド結果を動かします。
npx @vinext/cloudflare deploy --dry-run
npx @vinext/cloudflare deploy
初回は cf auth login でログインするか、CI なら CLOUDFLARE_API_TOKEN を設定します。アカウント ID は cloudflare.config.ts の accountId か、環境変数 CLOUDFLARE_ACCOUNT_ID で渡します3。筆者は --dry-run まで実行し、実際のデプロイはしていません。
OpenNext は、Cloudflare のガイドどおり手で設定します。2026 年 10 月時点の公式ガイドでは「Wrangler の自動設定は Next.js に vinext を使う。OpenNext を使うなら手で設定する」と書かれています2。筆者が試した手順は次のとおりです(@opennextjs/cloudflare 1.20.8、Wrangler 4.147.0)。
npm i @opennextjs/cloudflare@latest
npm i -D wrangler@latest
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "my-next-app",
"main": ".open-next/worker.js",
"compatibility_date": "2026-09-28",
"compatibility_flags": ["nodejs_compat"],
"assets": { "directory": ".open-next/assets", "binding": "ASSETS" },
"observability": { "enabled": true }
}
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
export default defineCloudflareConfig();
{
"scripts": {
"preview": "opennextjs-cloudflare build && opennextjs-cloudflare preview",
"deploy": "opennextjs-cloudflare build && opennextjs-cloudflare deploy",
"cf-typegen": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts"
}
}
nodejs_compat フラグと、2024-09-23 以降の互換日付が必須です2。.open-next は .gitignore に入れます。npx opennextjs-cloudflare build は next build を走らせたあと、.open-next/worker.js を出力しました。wrangler deploy --dry-run で見たアップロード量は 4,637 KiB(gzip 975 KiB)です。64 MiB の上限には十分収まります。
vinext には公式の Agent Skill(migrate-to-vinext)があり、Claude Code に移行を任せられます110。スキルの仕組みは Claude Code のスキルの作り方 で詳しく説明しています。
-
Next.js プロジェクトのルートでスキルを入れる
npx skills add cloudflare/vinext -a claude-code -y --copy
筆者の環境では ./.claude/skills/migrate-to-vinext に入りました。CLI は最後に「使う前にスキルを確認すること。エージェントの全権限で動く」と表示します。中身の SKILL.md に一度目を通してください
-
Claude Code を起動して、公式どおりに頼む
migrate this project to vinext
-
スキルの流れを確認する。スキルは次の順で進めるよう書かれています10
package.json に next があるか確かめる(なければ止まる)
vinext check で互換性を調べ、致命的な問題があれば先に報告する
vinext init を実行し、失敗したら手作業の移行に切り替える
dev:vinext で開発サーバーが起動するか確かめる
スキルには「やってはいけないこと」も書かれています。app/ や pages/ のコードを書き換えない、next/* の import を vinext/* に書き換えない、getPlatformProxy() を使わない、などです10。Claude Code が余計な書き換えをしたら、この一覧を根拠に差し戻せます。
vinext init は「エージェントはデプロイ先をユーザーに聞くこと」とも定めています3。Claude Code から Cloudflare か Node.js かを聞かれたら、--platform=cloudflare を選びます。Claude Code で Workers アプリ全体を作る流れは Claude Code で Cloudflare Workers アプリを作る全手順 にまとめています。
vinext では、Server Components・Route Handlers・Server Actions のどこからでも cloudflare:workers の env を読めます。独自の Worker エントリーは要りません3。
import { env } from "cloudflare:workers";
export default async function Page() {
const result = await env.DB.prepare("SELECT * FROM posts").all();
return <div>{JSON.stringify(result)}</div>;
}
バインディングは cloudflare.config.ts の env に bindings.d1({ name: "my-db" }) や bindings.kv() の形で足します3。型は dev・build のときに .cloudflare/types に生成されます。tsconfig.json の include にこのディレクトリを足してください(vinext init の完了メッセージでも案内されます)。
ISR やデータキャッシュを本番で使う場合は、キャッシュの置き場を決めます。KV を "use cache" のデータキャッシュに使う kvDataAdapter() や、Workers Cache からページを返す workersCacheCdnAdapter() などが用意されています3。何も設定しないとメモリ上のキャッシュになり、isolate をまたいで共有されません。
筆者が実際に引っかかった点と、公式に書かれている注意点です。
| 症状 | 原因 | 対処 |
|---|
vinext init が ERESOLVE で止まる | react-server-dom-webpack@19.3.0 が React 19.3 以上を要求し、create-next-app 直後の React 19.2.8 と合わない | npm i react@19.3.0 react-dom@19.3.0 で React を上げてから init し直す |
対話なしの vinext init が止まる | Cloudflare のキャッシュと画像の選択が必要 | --cdn-cache --data-cache --image-optimization を明示する |
Cannot find native binding(rolldown) | npm の optional dependencies の不具合 | node_modules と package-lock.json を消して npm i し直す |
プレビューで requires compatibility date "2026-10-05" | 生成された互換日付が、ローカルの workerd が対応する最新日(今回は 2026-09-28)より新しい | compatibilityDate を表示された日付に下げるか、パッケージを更新する |
OpenNext で runtime = "edge" のページが動かない | OpenNext は Node.js ランタイムで動かす | export const runtime = "edge" を消す |
ほかに、公式に書かれている制限を挙げます。
- Cache Components と PPR: vinext は
"use cache" に部分的に対応していますが、cacheComponents の振る舞いはまだ揃っていません3
- ネイティブモジュール:
sharp・satori などは、vinext の App Router の開発モードで失敗することがあります。本番ビルドのほうが対応範囲は広いです3
- Vercel 固有の機能:
@vercel/og の edge ランタイム、Vercel Analytics、Vercel KV/Blob/Postgres は vinext の対象外です3
- Windows: OpenNext は Windows を限定的にしかサポートしていません。WSL か Linux の CI でのビルドが推奨されています4
- CPU 時間: Free プランの CPU 時間は 1 リクエスト 10 ms です。SSR の重いページは Paid(既定 30 秒、最大 5 分)を前提に考えます6
Workers と他のサーバーレスの違いは Cloudflare Workers と AWS Lambda の比較 を参照してください。2026 年 9 月の発表全体は Cloudflare Birthday Week 2026 の発表まとめ にまとめています。
- Cloudflare は 2026 年 10 月時点で、Next.js on Workers の既定を vinext にしている。OpenNext は既存アプリの保守向け
- vinext は Next.js 16 専用で、Vite で API を再実装する。OpenNext は
next build の出力を変換するので、14・15 や細かい機能に強い
- 移行は
vinext check → vinext init → build:vinext → @vinext/cloudflare deploy。既存の next dev は残る
- Claude Code なら
npx skills add cloudflare/vinext のあと「migrate this project to vinext」と頼むだけ。スキルの禁止事項でレビューする
- Worker の上限が 64 MiB になり、サイズで OpenNext を諦める理由は減った。決め手は互換性
次にやることは、手元の Next.js アプリで npx vinext check を 1 回流すことです。点数と「partial」の項目を見れば、vinext と OpenNext のどちらにするかを決められます。
使えますが、事前の確認が前提です。Cloudflare は 2026-09-28 に 1.0 を出して本番向けとしました5。一方、README は「まだすべてのアプリの置き換えにはならない」と書き、自分のアプリでの評価を求めています3。vinext check の結果と、使っている機能の対応状況を見て判断してください。
いいえ。OpenNext は今も Cloudflare の公式ガイドに載っています。vinext に移れない互換性の穴がある既存アプリでは、OpenNext を続けるのが公式の案内です2。Next.js 14・15 のアプリも OpenNext の対象です4。
vinext は Next.js 16.x だけを対象にしており、古いバージョンで非推奨になった API には対応しません3。先に Next.js 16 に上げるか、OpenNext を使います。
OpenNext の Get Started は、@cloudflare/next-on-pages が入っていれば外すよう案内しています。静的書き出し(output: "export")だけのサイトなら、Cloudflare Pages に置く方法も公式に残っています1。
2026-09-04 から、上限は非圧縮で 64 MiB(Free・Paid 共通)になり、圧縮後の上限はなくなりました7。筆者が試した OpenNext のアプリは 4.6 MiB でした。ただし、静的アセットは Free で 1 バージョンあたり 20,000 ファイル、1 ファイル 25 MiB までという別の上限があります6。