Documentation Index Fetch the complete documentation index at: https://mintlify.com/cloudflare/vinext/llms.txt
Use this file to discover all available pages before exploring further.
Installation
This guide covers everything you need to know about installing and configuring vinext, from basic setup to advanced customization.
Prerequisites
Before you begin, make sure you have:
Node.js 18+ installed
An existing Next.js project (or create a new one)
Basic familiarity with Next.js and Vite
vinext requires React 19.2.0+, React DOM 19.2.0+, and Vite 7.0.0+ as peer dependencies.
Installation Methods
Method 1: Using vinext init (Recommended)
The vinext init command automates the entire migration process:
Install vinext
Or use your preferred package manager:
Run the migration command
This command will:
Run compatibility check — Scans your project for potential issues
Install dependencies — Adds vite and @vitejs/plugin-rsc (for App Router) as devDependencies
Configure ESM — Adds "type": "module" to package.json
Rename CJS configs — Renames files like postcss.config.js to .cjs to avoid ESM conflicts
Add npm scripts — Adds dev:vinext and build:vinext to package.json
Generate vite.config.ts — Creates a minimal Vite configuration
Use vinext init --force to overwrite an existing vite.config.ts, or vinext init --skip-check to skip the compatibility report.
Start developing
Your app will be available at http://localhost:3001 (configurable with --port).
Method 2: Manual Installation
For more control over the setup process:
Install vinext and peer dependencies
npm install vinext react@^19.2.0 react-dom@^19.2.0 vite@^7.0.0
Update package.json
Add "type": "module" to enable ESM: {
"type" : "module" ,
"scripts" : {
"dev" : "vinext dev" ,
"build" : "vinext build" ,
"start" : "vinext start"
}
}
Create vite.config.ts (App Router only)
If your project uses the App Router (app/ directory), create a vite.config.ts: import { defineConfig } from "vite" ;
import vinext from "vinext" ;
import rsc from "@vitejs/plugin-rsc" ;
export default defineConfig ({
plugins: [
vinext (),
rsc ({
entries: {
rsc: "virtual:vinext-rsc-entry" ,
ssr: "virtual:vinext-app-ssr-entry" ,
client: "virtual:vinext-app-browser-entry" ,
},
}),
] ,
}) ;
For Pages Router projects, no vite.config.ts is needed. vinext auto-configures everything.
Handle CJS config files
If you have CommonJS config files (like postcss.config.js), rename them to .cjs to avoid conflicts: mv postcss.config.js postcss.config.cjs
mv tailwind.config.js tailwind.config.cjs
Configuration
Basic Configuration
For most projects, no vite.config.ts is required. vinext auto-detects your project structure and configures Vite automatically.
If you need custom Vite configuration:
import { defineConfig } from "vite" ;
import vinext from "vinext" ;
export default defineConfig ({
plugins: [ vinext ()] ,
// Your custom Vite config
server: {
port: 3000 ,
} ,
resolve: {
alias: {
"@" : "/src" ,
},
} ,
}) ;
App Router Configuration
For App Router projects with React Server Components:
import { defineConfig } from "vite" ;
import vinext from "vinext" ;
import rsc from "@vitejs/plugin-rsc" ;
export default defineConfig ({
plugins: [
vinext (),
rsc ({
entries: {
rsc: "virtual:vinext-rsc-entry" ,
ssr: "virtual:vinext-app-ssr-entry" ,
client: "virtual:vinext-app-browser-entry" ,
},
}),
] ,
}) ;
Cloudflare Workers Configuration
For deployment to Cloudflare Workers, add the Cloudflare Vite plugin:
import { defineConfig } from "vite" ;
import vinext from "vinext" ;
import rsc from "@vitejs/plugin-rsc" ;
import { cloudflare } from "@cloudflare/vite-plugin" ;
export default defineConfig ({
plugins: [
vinext (),
rsc ({
entries: {
rsc: "virtual:vinext-rsc-entry" ,
ssr: "virtual:vinext-app-ssr-entry" ,
client: "virtual:vinext-app-browser-entry" ,
},
}),
cloudflare ({
viteEnvironment: { name: "rsc" , childEnvironments: [ "ssr" ] },
}),
] ,
}) ;
The vinext deploy command auto-generates this configuration if it doesn’t exist, so you don’t need to create it manually unless you want custom settings.
Migrating from Next.js
File Structure
Your existing file structure works as-is:
my-app/
├── app/ # App Router (if using)
├── pages/ # Pages Router (if using)
├── public/ # Static files
├── next.config.js # Next.js config (works with vinext)
├── package.json
└── tsconfig.json
No need to move or rename files!
next.config.js
Your existing next.config.js (or .ts/.mjs) works with vinext. Most configuration options are supported:
export default {
reactStrictMode: true ,
basePath: "/docs" ,
trailingSlash: true ,
redirects : async () => [
{
source: "/old/:path*" ,
destination: "/new/:path*" ,
permanent: true ,
},
] ,
rewrites : async () => [
{
source: "/api/:path*" ,
destination: "https://api.example.com/:path*" ,
},
] ,
images: {
domains: [ "example.com" ],
} ,
} ;
webpack and Turbopack configuration options are ignored. Use Vite plugins instead.
Environment Variables
Environment variables work the same as in Next.js:
NEXT_PUBLIC_API_URL = https://api.example.com
API_SECRET_KEY = secret123
NEXT_PUBLIC_* variables are inlined at build time (client-side)
Other variables are available server-side only
TypeScript Configuration
Your existing tsconfig.json works with vinext. Path aliases are automatically resolved via vite-tsconfig-paths:
{
"compilerOptions" : {
"baseUrl" : "." ,
"paths" : {
"@/*" : [ "./src/*" ],
"@/components/*" : [ "./src/components/*" ]
}
}
}
Deploying to Cloudflare Workers
vinext makes it incredibly easy to deploy to Cloudflare Workers:
One-command deployment
This command automatically:
Detects App Router or Pages Router
Generates wrangler.jsonc and worker configuration
Installs required dependencies
Builds your application
Deploys to Cloudflare Workers
Deploy to preview environment
Test your deployment in a preview environment:
Custom Worker name
Deploy with a custom name: vinext deploy --name my-custom-name
Deploy Options
Production Deploy
Preview Deploy
Custom Name
Skip Build
Dry Run
Traffic-Aware Pre-Rendering (Experimental)
TPR queries Cloudflare zone analytics at deploy time to find which pages actually get traffic, pre-renders only those, and uploads them to KV cache:
vinext deploy --experimental-tpr
Advanced TPR options:
Default (90% coverage)
Higher Coverage
Limited Pages
Custom Time Window
vinext deploy --experimental-tpr
TPR requires:
A custom domain (zone analytics unavailable on *.workers.dev)
CLOUDFLARE_API_TOKEN environment variable with Zone.Analytics read permission
Caching with Cloudflare KV
For production ISR caching, use the built-in KV cache handler:
import { KVCacheHandler } from "vinext/cloudflare" ;
import { setCacheHandler } from "next/cache" ;
// This should be called once during app initialization
export function register () {
if ( typeof env !== "undefined" && env . MY_KV_NAMESPACE ) {
setCacheHandler ( new KVCacheHandler ( env . MY_KV_NAMESPACE ));
}
}
Make sure to bind a KV namespace in wrangler.jsonc:
{
"name" : "my-app" ,
"main" : "vinext/server/app-router-entry" ,
"compatibility_date" : "2024-01-01" ,
"kv_namespaces" : [
{
"binding" : "MY_KV_NAMESPACE" ,
"id" : "your-kv-namespace-id"
}
]
}
Compatibility Checking
Before fully committing to vinext, check your project for compatibility:
This produces a detailed report showing:
✅ Supported features you’re using
🟡 Partially supported features
❌ Unsupported features that need attention
Example Output
vinext check
Scanning project...
✓ Imports
✅ next/link
✅ next/navigation (usePathname, useRouter)
✅ next/headers (cookies, headers)
🟡 next/image (local image optimization unavailable)
✓ Routing
✅ App Router detected
✅ Dynamic routes: [id].tsx
✅ Catch-all routes: [...slug].tsx
✓ Features
✅ Server Components
✅ Server Actions
✅ Middleware
❌ Turbopack (not supported, will use Vite)
✓ Configuration (next.config.js)
✅ redirects
✅ rewrites
✅ basePath
🟡 images.domains (parsed but not used for optimization)
Compatibility: 94% (47/50 features supported)
Advanced Configuration
Custom Vite Plugins
Add any Vite plugins you need:
import { defineConfig } from "vite" ;
import vinext from "vinext" ;
import react from "@vitejs/plugin-react" ;
export default defineConfig ({
plugins: [
vinext (),
react ({
// React plugin options
}),
] ,
}) ;
MDX Support
For MDX support (e.g., with Nextra), add the MDX plugin:
import { defineConfig } from "vite" ;
import vinext from "vinext" ;
import mdx from "@mdx-js/rollup" ;
export default defineConfig ({
plugins: [
vinext (),
mdx (),
] ,
}) ;
The vinext deploy command auto-detects MDX usage and configures it automatically.
Path Aliases
Path aliases from your tsconfig.json are automatically resolved. No additional configuration needed!
{
"compilerOptions" : {
"paths" : {
"@/*" : [ "./src/*" ]
}
}
}
Use them in your code:
import { Button } from "@/components/Button" ;
Troubleshooting
Dual Package Hazard
If you see “Invalid hook call” errors or React warnings about multiple React copies:
import { defineConfig } from "vite" ;
import vinext from "vinext" ;
export default defineConfig ({
plugins: [ vinext ()] ,
resolve: {
dedupe: [
"react" ,
"react-dom" ,
"react/jsx-runtime" ,
"react/jsx-dev-runtime" ,
],
} ,
}) ;
ESM/CJS Conflicts
If you see errors like “require() of ES Module not supported”:
Add "type": "module" to package.json
Rename .js config files to .cjs (e.g., postcss.config.cjs)
Use export default instead of module.exports in config files
Native Node Modules
Some packages (sharp, resvg, satori, lightningcss, @napi-rs/canvas) crash Vite’s RSC dev environment. These are auto-stubbed during vinext deploy.
For local development, dynamic OG image routes using these packages work in production builds but not in dev mode.
TypeScript Errors
If you see TypeScript errors about missing types:
npm install -D @types/react @types/react-dom @types/node
Build Failures
If your build fails:
Check that you have all peer dependencies installed
For App Router, ensure @vitejs/plugin-rsc is installed
Run vinext check to identify compatibility issues
Check the build output for specific error messages
Next Steps
CLI Reference Explore all vinext CLI commands
API Coverage See what Next.js features are supported
Live Examples Browse deployed examples on Cloudflare Workers
GitHub Repository View the source code and contribute