12k
All articles

Vite上に構築されたNext.jsの代替、Vinextとは

VinextでNext.jsアプリをVite上で動かす方法、対応APIとデプロイ先、互換性の制限、既存プロジェクトのテスト手順を紹介します。

OpenReplay Team
OpenReplay Team
Vite上に構築されたNext.jsの代替、Vinextとは

Vinextは、CloudflareがオープンソースとしてリリースしているViteプラグインです。Next.jsのAPIを再実装しているため、既存のApp RouterやPages RouterのコードベースをNext.jsのツールチェーンではなくViteでビルド・配信できます。Cloudflareは2026年9月28日にバージョン1.0を発表しました。

Next.js自体は気に入っているものの、それに付随するホスティング環境には不満があるというチームは少なくありません。とはいえ、ホスティング先を変えるためだけに大規模なアプリを別のフレームワークへ移植するのは、なかなか正当化しにくいものです。Vinextはそこに別の選択肢を提示します。本記事では、Vinextがサポートする機能、デプロイ先、自分のアプリで試すための具体的なコマンド、そしてCloudflare自身が公表している未対応領域について解説します。

要点

  • Vinextはapp/、pages/、next.configの各ファイルをそのまま残し、それらをビルド・配信するレイヤーだけを置き換えます。つまり、書き直しではなく「プラットフォームの移行」です。
  • Cloudflareは2種類の互換性の数値を公表しています。1.0の発表では、要望の多い機能(Cache Componentsを除く)について99%以上のテスト互換性があるとしており、READMEではNext.js 16のAPIサーフェスの約94%が完全または部分的にサポートされているとしています。
  • npx vinext checkはNext.jsプロジェクトをスキャンして既知の非互換箇所を検出し、npx vinext initはnext devを壊すことなくプロジェクトをVinext向けにセットアップします。
  • 主要なデプロイ先はCloudflare Workersです。NetlifyやAWSなどその他のホスティング先には、Nitro Viteプラグインを介してデプロイします。
  • Cache Componentsのサポートは部分的です。また、VinextのREADMEでは、実績のある本番環境での動作が必要なアプリにはOpenNextの方が成熟した選択肢であると明記されています。

Vinextとは何か、他のNext.js代替とどう違うのか

Vinextは、CloudflareがVite上に再実装したNext.jsです。2026年2月に1週間のAI主導の実験として始まり、その7か月後に1.0に到達しました。READMEには、これがフォークではないことが明記されています。コア部分は、Next.jsの公開APIに合わせてゼロから書き起こされたものです。

そのため、Vinextは一般的なNext.jsの代替とは性質の異なる選択肢です。React Router、Astro、SvelteKitに移行する場合は、ルーティング、データ取得、コンポーネントを書き直す必要があります。Vinextはそうしたコードには手を付けず、それをビルド・配信する部分だけを変更します。プロジェクトの見た目はNext.jsのままで、その下でViteが処理を担います。

Vinextがサポートする機能

Vinextは両方のルーターと、モダンなNext.jsの主要なサーバー機能をカバーしています。1.0の発表とREADMEには、以下のサポートが記載されています。

  • App Router、Pages Router、および両方を併用するハイブリッドアプリ
  • React Server ComponentsとServer Actions
  • Middleware、APIルート、ルートハンドラー
  • ISRによる再検証(revalidation)
  • generateStaticParams()とgetStaticPaths()によるビルド時のプリレンダリング
  • output: "export"による静的エクスポート

READMEではNext.js 16.xを対象としており、peer dependencyとしてvite ^8.0.0が指定されています。

CloudflareはVinextのNext.js互換性を2通りの方法で示していますが、この2つの数値は同じものを測っているわけではありません。1.0の発表記事では99%以上のテスト互換性をうたっていますが、これは顧客からの要望が多かった機能に限った数値で、Cache Componentsは除外されています。一方READMEでは、「Next.js 16のAPIサーフェスの約94%が完全または部分的にサポートされている」と記載されています。どちらの数値もCloudflareによるものであり、実際に自分のアプリで動かしてみることの代わりにはなりません。

Vinextのデプロイ先

VinextはCloudflare Workersにネイティブでデプロイでき、1.0の発表記事によればWorkersの無料プランでも動作します。同記事ではNetlifyとAWS Lambdaもデプロイ先として挙げられています。その仕組みはREADMEで説明されており、Workersは@vinext/cloudflareが直接処理し、Vercel、Netlify、AWS、Deno DeployにはNitro Viteプラグインを追加して対応します。NetlifyやLambda向けのネイティブアダプターが使われているわけではありません。

最小構成では、プラグインを1つ追加するだけです。

// vite.config.ts
import { defineConfig } from "vite";
import vinext from "vinext";

export default defineConfig({
  plugins: [vinext()],
});

Cloudflare以外のホスティング先を対象にする場合は、nitroをインストールしてそのプラグインを追加します。

// vite.config.ts
import { defineConfig } from "vite";
import vinext from "vinext";
import { nitro } from "nitro/vite";

export default defineConfig({
  plugins: [vinext(), nitro()],
});
npm install nitro
NITRO_PRESET=netlify npx vite build

既存のNext.jsアプリでVinextを試す方法

既存のアプリでVinextを試すのに必要なコマンドは2つだけで、どちらも現在のNext.jsのワークフローを妨げることはありません。ブランチ上で実行してください。

npx vinext check
npx vinext init

vinext checkは、何かを変更する前にプロジェクトをスキャンし、既知の非互換箇所をレポートします。vinext initは非破壊的なので、新しいセットアップと並行してnext devも引き続き動作します。実行時にはデプロイ先を尋ねられ、デフォルトはCloudflareです。1.0リリース以降、Cloudflare向けのセットアップでは、型付けされたcloudflare.config.tsを用いるcf CLIがデフォルトで使われます。従来のWranglerによるセットアップを使い続けたい場合は、--legacy-wrangler-cloudflare-initを指定します。

新しいVinextアプリを始める

新規プロジェクトの場合は、アプリのひな形を作成し、起動、ビルドしてからデプロイします。

npm create vinext-app@latest my-app
npx vite dev
npx vite build
npx @vinext/cloudflare deploy

1.0リリースでは、deployコマンドに--warm-cacheフラグが追加されました。これは新しいバージョンをトラフィック0%の状態でアップロードし、そのバージョンを経由してキャッシュ可能なページにリクエストを送ってキャッシュを充填したうえで、初めて本番に昇格させるものです。

Vinextの制約と既知の未対応領域

READMEのKnown gapsセクションには、VinextがまだNext.jsと同等になっていない領域として、Cache Components、ビルド時の画像・フォント最適化、App Routerの開発環境におけるネイティブモジュール、一部のプラットフォーム固有のルート設定の4つが挙げられています。Cloudflareはこの4つすべてに引き続き取り組んでいるとしており、いずれも恒久的な制約ではありません。

  • Cache ComponentsとPPR: "use cache"は部分的に動作しますが、cacheComponentsモデル全体はまだ完成していません。キャッシュプロファイル、タグ、部分的なシェル、レジューム、プリフェッチ、開発時およびビルド時のキャッシュの一部については、依然としてNext.jsと異なる動作をする可能性があります。
  • 画像とフォント: Cloudflare上では、画像はリクエスト時に最適化できます。ただし、Next.jsがビルド時に実行する画像パイプライン全体はまだ再現されておらず、フォントもビルド時に処理されるのではなく、ランタイムで読み込まれます。
  • ネイティブモジュール: sharp、resvg、satori、lightningcss、@napi-rs/canvasなどのパッケージは、ViteのRSC開発環境で動作しない場合があります。本番ビルドでは、開発モードよりも多くのパッケージに対応しています。
  • ルート設定: Vinextは、ルート設定のruntimeとpreferredRegionを無視します。

また、READMEには、Vinextはまだすべてのアプリケーションに対してドロップインで置き換えられるものではないとも記載されています。

Vinextを採用すべきチーム、待つべきチーム

Vinextは、特定のホスティング先に縛られずにNext.jsで開発を続けたいチームに適しています。ただし、本番環境での利用可否については、情報源によって見解が完全には一致していません。Cloudflareの発表では1.0を本番環境に対応済み(production-ready)としている一方、READMEでは「注意すれば使える(You can, with caution)」と答えており、Vinextにはまだ互換性の未対応領域があること、そしてあらゆる種類の本番Next.jsアプリで実証されたわけではないことを指摘しています。

  • 採用する: アプリで両方のルーター、RSC、Server Actions、ISRを使用しており、Workersに、またはNitro経由でデプロイしたい場合。
  • 待つ: Cache Components、PPR、あるいはタグやプロファイルといった"use cache"のセマンティクスに大きく依存している場合。
  • OpenNextを検討する: 本番環境での実証された成熟度が必要な場合。VinextのREADMEによると、OpenNextはnext buildの出力をもとに動作するため、Next.jsのAPIをより広くカバーしており、実績もはるかに豊富です。

まとめ

Vinextを使えば、Next.jsアプリを書き直すことなくVercelから離れることができます。ただし、主にCache Components周辺に存在する、公表済みの未対応領域は受け入れる必要があります。自分のアプリに適しているかどうかを確かめるには、ブランチを作成してnpx vinext checkを実行し、検出された内容を既知の未対応領域と照らし合わせたうえで、npx vinext initを実行してnext devと動作を比較してください。ツールチェーンの残りの部分も移行したい場合は、Getting Started with Vite+を参照してください(READMEには、Vite+プロジェクト向けにvp exec vinext-cloudflare deployが記載されています)。initがセットアップするcloudflare.config.tsのワークフローについては、「A Practical Guide to Cloudflare’s New cf CLI」を参照してください。

よくある質問

Vinextに移行する際、独自のwebpack設定やnext/jestのセットアップはそのまま使えますか?

いいえ。VinextはVite上で動作するため、Turbopackやwebpackの設定は適用されず、独自のwebpackローダーやプラグインはViteプラグインに置き換える必要があります。VinextのREADMEでは、next/jestは非サポートとされており、代わりにVitestが推奨されています。AMPも非サポートで、useAmp()は常にfalseを返します。また、従来のnext exportコマンドは、Next.jsの設定でoutput: 'export'を指定する方式に置き換えられています。

Vinextに必要なReactとViteのバージョンは何ですか?

Vinextはpeer dependencyとして、react ^19.3.1、react-dom ^19.3.1、react-server-dom-webpack ^19.3.1、vite ^8.0.0を宣言しており、Next.js 16.xを対象としています。App Routerのプロジェクトでは、@vitejs/plugin-rscもインストールされている必要があります。Vinextはappディレクトリを検出するとこのプラグインを自動的に登録するため、vinext()にrsc: falseを渡さない限り、独自にrsc()の呼び出しを追加すると、プラグインの重複エラーでビルドが失敗します。

vinext initは既存のNext.jsプロジェクトに対してどのような変更を加えますか?

vinext initは、package.jsonに'type': 'module'を追加し、ESMとの競合を避けるために、postcss.config.jsをpostcss.config.cjsにするなど、CommonJSの設定ファイルの名前を変更します。また、ViteとVinextのパッケージをインストールし、既存のNext.jsのスクリプトと並べてdev:vinext、build:vinext、start:vinextのスクリプトを追加します。元のスクリプトはそのまま残るため、同じコードベースからnext devとVinextの開発サーバーの両方を実行し、並べて比較できます。

Cloudflare上のVinextでは、revalidateTagで再生成中に古いページが配信されますか?

はい。2026年10月の1.1系リリース以降、revalidateTag(tag, 'max')のようにキャッシュプロファイルを渡した場合に対応しています。以前のリリースでは、該当するページがWorkers Cacheからパージされていたため、次のリクエストは完全なレンダリングを待つ必要がありました。現在では、Workers CacheとResponse Storeがそれらのエントリを古い(stale)ものとしてマークし、バックグラウンドで再生成している間もキャッシュされたバージョンを配信し続けます。これはNext.jsと同じ動作です。タグのみを指定してrevalidateTagを呼び出した場合や、expire: 0を指定した場合は、引き続きエントリが即座に失効します。古くなった'use cache'のエントリも、再生成中は配信されます。

DevTools for the frontend

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.