Skip to main content

Migrating from Next.js

vinext reimplements the Next.js API surface on Vite, allowing you to run existing Next.js applications with a different toolchain. This guide covers both automated and manual migration approaches.

Automated Migration

The fastest way to migrate is using vinext init, which automates all migration steps:

What vinext init Does

1

Compatibility Check

Runs vinext check to scan your project for compatibility issues and provides a detailed report of supported and unsupported features.
2

Install Dependencies

Installs required dependencies based on your router type:
  • vite (always required)
  • @vitejs/plugin-rsc (for App Router projects)
  • vinext (the main plugin)
3

ESM Configuration

Adds "type": "module" to your package.json and renames CommonJS config files to .cjs extension to avoid conflicts:
  • postcss.config.jspostcss.config.cjs
  • tailwind.config.jstailwind.config.cjs
4

Add Scripts

Adds vinext scripts to package.json alongside your existing Next.js scripts:
5

Generate Vite Config

Creates a minimal vite.config.ts with the vinext plugin:

Migration Options

Non-Destructive Migration

The migration is completely non-destructive:
  • Your existing Next.js setup continues to work
  • next.config.js, tsconfig.json, and source files are not modified
  • Next.js dependencies are not removed
  • Both toolchains can run side-by-side

Manual Migration

If you prefer manual setup or need more control:
1

Install vinext

2

Update package.json

Replace Next.js commands with vinext:
3

Run Compatibility Check

Before starting development, check for compatibility issues:
This scans your codebase and reports:
  • Supported features currently in use
  • Unsupported features that may cause issues
  • Recommended migration steps
4

Start Development

Run the dev server with hot module replacement:
vinext auto-detects your app/ or pages/ directory and loads your next.config.js automatically.

Compatibility Check

The vinext check command scans your Next.js application and provides a detailed compatibility report:

What It Checks

  • Router Type: App Router vs Pages Router
  • Next.js Features: Identifies features like ISR, middleware, i18n routing
  • API Usage: Scans for next/* module imports
  • Configuration: Reviews next.config.js for supported options
  • Dependencies: Checks for ecosystem libraries (next-themes, nuqs, etc.)

Example Output

Common Migration Patterns

TypeScript Path Aliases

vinext automatically resolves TypeScript path aliases from tsconfig.json:
No additional configuration needed—imports like import { Button } from '@/components/ui' work automatically.

MDX Support

If your project uses MDX, vinext auto-detects it and configures @mdx-js/rollup:
vinext extracts the remark/rehype plugins from your Next.js config and applies them automatically.

Environment Variables

NEXT_PUBLIC_* variables work exactly as in Next.js:

Static Assets

The public/ directory works identically:

Known Differences

Image Optimization

Next.js: Build-time optimization with automatic format conversion and resizing. vinext: Runtime optimization via CDN or Cloudflare Images binding. No build-time processing.
Remote images are handled by @unpic/react, which auto-detects 28+ CDN providers.

Font Loading

Next.js: Fonts are downloaded and self-hosted at build time. vinext: Fonts are loaded from Google Fonts CDN at runtime.

Build Output

Next.js: Creates .next/ directory with server and client bundles. vinext:
  • Creates dist/ directory with multi-environment builds
  • App Router: Separate RSC, SSR, and client bundles
  • Pages Router: Server and client bundles

Migration Checklist

  • Run vinext check to identify compatibility issues
  • Review the API Coverage page for unsupported features
  • Check if your dependencies are compatible
  • Backup your project (or commit current state to git)
  • Review the Known Limitations section
  • Run vinext init or manually install vinext
  • Test dev server with vinext dev
  • Verify all routes are discovered correctly
  • Check that data fetching works (getStaticProps, Server Components)
  • Test client-side navigation and prefetching
  • Verify environment variables are loaded
  • Check that middleware runs correctly (if applicable)
  • Run production build with vinext build
  • Test production server with vinext start
  • Verify static assets are served correctly
  • Test API routes (Pages Router) or route handlers (App Router)
  • Check that error pages (404, 500) render correctly
  • Run your test suite
  • Review build output size and compare to Next.js

Troubleshooting

ESM/CJS Conflicts

Error: require is not defined or exports is not defined Solution: Your project needs "type": "module" in package.json. The vinext init command handles this automatically.

Missing Virtual Modules

Error: Cannot find module 'virtual:vinext-*' Solution: These are Vite virtual modules. Make sure you’re using vinext dev or vinext build, not raw vite commands.

Route Not Found

Error: 404 on routes that exist in your filesystem Solution:
  • Check that files have default exports
  • Verify file extensions (.tsx, .ts, .jsx, .js) are standard
  • Check for syntax errors that prevent module loading
  • Run with DEBUG=vinext:routing to see route discovery logs

Middleware Not Running

Error: Middleware doesn’t execute on requests Solution:
  • Ensure middleware.ts is at project root or in src/
  • Check the matcher config if you’re using path-based matching
  • Verify middleware has a default export

Type Errors

Error: TypeScript errors on next/* imports Solution: vinext is API-compatible with Next.js types. If you see type errors:

Getting Help

If you encounter issues during migration:

Next Steps

After migrating your application:

Configuration Guide

Learn how to configure vinext and customize the Vite setup

Deploy to Cloudflare

Deploy your application to Cloudflare Workers

Static Export

Generate a fully static site for any hosting provider

API Reference

Explore the complete vinext API