---
id: sm-migrate-to-vinext
name: "migrate-to-vinext"
url: https://skills.yangsir.net/skill/sm-migrate-to-vinext
author: cloudflare
domain: ai-frontend-engineering
tags: ["vercel", "nextjs", "cloud-migration", "frontend-deployment", "serverless-functions"]
install_count: 8100
rating: 4.50 (64 reviews)
github: https://github.com/cloudflare/vinext
---

# migrate-to-vinext

> 将Next.js应用迁移到基于Vite的vinext框架，实现API兼容和包替换式迁移。

**Stats**: 8,100 installs · 4.5/5 (64 reviews)

## Before / After 对比

### Next.js应用平滑迁移至Vinext

## Readme

# migrate-to-vinext

# Migrate Next.js to vinext

vinext reimplements the Next.js API surface on Vite. Existing `app/`, `pages/`, and `next.config.js` work as-is — migration is a package swap, config generation, and ESM conversion. No changes to application code required.

## FIRST: Verify Next.js Project

Confirm `next` is in `dependencies` or `devDependencies` in `package.json`. If not found, STOP — this skill does not apply.

Detect the package manager from the lockfile:

Lockfile
Manager
Install
Uninstall

`pnpm-lock.yaml`
pnpm
`pnpm add`
`pnpm remove`

`yarn.lock`
yarn
`yarn add`
`yarn remove`

`bun.lockb` / `bun.lock`
bun
`bun add`
`bun remove`

`package-lock.json` or none
npm
`npm install`
`npm uninstall`

Detect the router: if an `app/` directory exists at root or under `src/`, it's App Router. If only `pages/` exists, it's Pages Router. Both can coexist.

## Quick Reference

Command
Purpose

`vinext check`
Scan project for compatibility issues, produce scored report

`vinext init`
Automated migration — installs deps, generates config, converts to ESM

`vinext dev`
Development server with HMR

`vinext build`
Production build (multi-environment for App Router)

`vinext start`
Local production server

`vinext deploy`
Build and deploy to Cloudflare Workers

## Phase 1: Check Compatibility

Run `vinext check` (install vinext first if needed via `npx vinext check`). Review the scored report. If critical incompatibilities exist, inform the user before proceeding.

See [references/compatibility.md](https://github.com/cloudflare/vinext/blob/HEAD/.agents/skills/migrate-to-vinext/references/compatibility.md) for supported/unsupported features and ecosystem library status.

## Phase 2: Automated Migration (Recommended)

Run `vinext init`. This command:

- Runs `vinext check` for a compatibility report

- Installs `vite` as a devDependency (and `@vitejs/plugin-rsc` for App Router)

- Adds `"type": "module"` to package.json

- Renames CJS config files (e.g., `postcss.config.js` → `.cjs`) to avoid ESM conflicts

- Adds `dev:vinext` and `build:vinext` scripts to package.json

- Generates a minimal `vite.config.ts`

This is non-destructive — the existing Next.js setup continues to work alongside vinext. Use the `dev:vinext` script to test before fully switching over.

If `vinext init` succeeds, skip to Phase 4 (Verify). If it fails or the user prefers manual control, continue to Phase 3.

## Phase 3: Manual Migration

Use this as a fallback when `vinext init` doesn't work or the user wants full control.

### 3a. Replace packages

```
# Example with npm:
npm uninstall next
npm install vinext
npm install -D vite
# App Router only:
npm install -D @vitejs/plugin-rsc

```

### 3b. Update scripts

Replace all `next` commands in `package.json` scripts:

Before
After
Notes

`next dev`
`vinext dev`
Dev server with HMR

`next build`
`vinext build`
Production build

`next start`
`vinext start`
Local production server

`next lint`
`vinext lint`
Delegates to eslint/oxlint

Preserve flags: `next dev --port 3001` → `vinext dev --port 3001`.

### 3c. Convert to ESM

Add `"type": "module"` to package.json. Rename any CJS config files:

- `postcss.config.js` → `postcss.config.cjs`

- `tailwind.config.js` → `tailwind.config.cjs`

- Any other `.js` config that uses `module.exports`

### 3d. Generate vite.config.ts

See [references/config-examples.md](https://github.com/cloudflare/vinext/blob/HEAD/.agents/skills/migrate-to-vinext/references/config-examples.md) for config variants per router and deployment target.

**Pages Router (minimal):**

```
import vinext from "vinext";
import { defineConfig } from "vite";
export default defineConfig({ plugins: [vinext()] });

```

**App Router (minimal):**

```
import vinext from "vinext";
import { defineConfig } from "vite";
export default defineConfig({ plugins: [vinext()] });

```

vinext auto-registers `@vitejs/plugin-rsc` for App Router when the `rsc` option is not explicitly `false`. No manual RSC plugin config needed for local development.

## Phase 4: Deployment (Optional)

### Option A: Cloudflare Workers (recommended for Cloudflare)

If the user wants to deploy to Cloudflare Workers, use `vinext deploy`. It auto-generates `wrangler.jsonc`, worker entry, and Vite config if missing, installs `@cloudflare/vite-plugin` and `wrangler`, then builds and deploys.

For manual setup or custom worker entries, see [references/config-examples.md](https://github.com/cloudflare/vinext/blob/HEAD/.agents/skills/migrate-to-vinext/references/config-examples.md).

#### Cloudflare Bindings (D1, R2, KV, AI, etc.)

To access Cloudflare bindings (D1, R2, KV, AI, Queues, Durable Objects, etc.), use `import { env } from "cloudflare:workers"` in any server component, route handler, or server action:

```
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>;
}

```

This works because `@cloudflare/vite-plugin` runs server environments in workerd, where `cloudflare:workers` is a native module. No custom worker entry, no `getPlatformProxy()`, no special configuration needed. Just import and use.

Bindings must be defined in `wrangler.jsonc`. For TypeScript types, run `wrangler types`.

**IMPORTANT:** Do not use `getPlatformProxy()`, `getRequestContext()`, or custom worker entries with `fetch(request, env)` to access bindings. These are older patterns. `cloudflare:workers` is the recommended approach and works out of the box with vinext.

### Option B: Other platforms (via Nitro)

For deploying to Vercel, Netlify, AWS, Deno Deploy, or any other [Nitro-supported platform](https://v3.nitro.build/deploy), add the Nitro Vite plugin:

```
npm install nitro

```

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

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

```

Build and deploy:

```
NITRO_PRESET=vercel npx vite build    # Vercel
NITRO_PRESET=netlify npx vite build   # Netlify
NITRO_PRESET=deno_deploy npx vite build  # Deno Deploy
NITRO_PRESET=node npx vite build      # Node.js server

```

Nitro auto-detects the platform in most CI/CD environments, so the preset is often unnecessary.

**Note:** For Cloudflare Workers, Nitro works but the native integration (`vinext deploy` / `@cloudflare/vite-plugin`) is recommended for the best developer experience with `cloudflare:workers` bindings, KV caching, and one-command deploys.

## Phase 5: Verify

- Run `vinext dev` to start the development server

- Confirm the server starts without errors

- Navigate key routes and check functionality

- Report the result to the user — if errors occur, share full output

See [references/troubleshooting.md](https://github.com/cloudflare/vinext/blob/HEAD/.agents/skills/migrate-to-vinext/references/troubleshooting.md) for common migration errors.

## Known Limitations

Feature
Status

`next/image` optimization
Remote images via @unpic; no build-time optimization

`next/font/google`
CDN-loaded, not self-hosted

Domain-based i18n
Not supported; path-prefix i18n works

`next/jest`
Not supported; use Vitest

Turbopack/webpack config
Ignored; use Vite plugins instead

`runtime` / `preferredRegion`
Route segment configs ignored

PPR (Partial Prerendering)
Use `"use cache"` directive instead (Next.js 16 approach)

## Anti-patterns

- **Do not modify `app/`, `pages/`, or application code.** vinext shims all `next/*` imports — no import rewrites needed.

- **Do not rewrite `next/*` imports** to `vinext/*` in application code. Imports like `next/image`, `next/link`, `next/server` resolve automatically.

- **Do not copy webpack/Turbopack config** into Vite config. Use Vite-native plugins instead.

- **Do not skip the compatibility check.** Run `vinext check` before migration to surface issues early.

- **Do not remove `next.config.js`** unless replacing it with `next.config.ts` or `.mjs`. vinext reads it for redirects, rewrites, headers, basePath, i18n, images, and env config.

- **Do not use `getPlatformProxy()` or custom worker entries for bindings.** Use `import { env } from "cloudflare:workers"` instead. This is the modern pattern and works out of the box with vinext and `@cloudflare/vite-plugin`.

- **For Cloudflare Workers, prefer the native integration over Nitro.** `vinext deploy` / `@cloudflare/vite-plugin` provides the best experience with `cloudflare:workers` bindings, KV caching, and image optimization. Nitro works for Cloudflare but the native setup is recommended.

Weekly Installs1.9KRepository[cloudflare/vinext](https://github.com/cloudflare/vinext)GitHub Stars6.9KFirst SeenFeb 24, 2026Security Audits[Gen Agent Trust HubPass](/cloudflare/vinext/migrate-to-vinext/security/agent-trust-hub)[SocketPass](/cloudflare/vinext/migrate-to-vinext/security/socket)[SnykPass](/cloudflare/vinext/migrate-to-vinext/security/snyk)Installed oncodex1.9Kopencode1.9Kgithub-copilot1.9Kcursor1.9Kgemini-cli1.9Kkimi-cli1.9K

---
*Source: https://skills.yangsir.net/skill/sm-migrate-to-vinext*
*Markdown mirror: https://skills.yangsir.net/api/skill/sm-migrate-to-vinext/markdown*