migrate-to-vinext

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Migrate Next.js to vinext

将Next.js迁移至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.
vinext 在Vite之上重实现了Next.js的API接口。现有
app/
pages/
目录及
next.config.js
可直接使用——迁移仅需替换依赖包、生成配置文件并转换为ESM格式,无需修改应用代码。

FIRST: Verify Next.js Project

第一步:验证Next.js项目

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:
LockfileManagerInstallUninstall
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.
确认
package.json
dependencies
devDependencies
中包含
next
。若未找到,请停止操作——本技能不适用当前项目。
通过锁文件检测包管理器:
锁文件管理器安装命令卸载命令
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
或无锁
npm
npm install
npm uninstall
检测路由类型:若根目录或
src/
下存在
app/
目录,则为App Router;若仅存在
pages/
目录,则为Pages Router。两种路由可共存。

Quick Reference

快速参考

CommandPurpose
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
命令用途
vinext check
扫描项目兼容性问题,生成带评分的报告
vinext init
自动化迁移——安装依赖、生成配置、转换为ESM格式
vinext dev
带HMR的开发服务器
vinext build
生产构建(App Router支持多环境)
vinext start
本地生产服务器
vinext deploy
构建并部署至Cloudflare Workers

Phase 1: Check Compatibility

阶段1:检查兼容性

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 for supported/unsupported features and ecosystem library status.
运行
vinext check
(若未安装vinext,可通过
npx vinext check
直接执行)。查看评分报告。若存在严重兼容性问题,请在继续操作前告知用户。
查看references/compatibility.md了解支持/不支持的功能及生态库状态。

Phase 2: Automated Migration (Recommended)

阶段2:自动化迁移(推荐)

Run
vinext init
. This command:
  1. Runs
    vinext check
    for a compatibility report
  2. Installs
    vite
    as a devDependency (and
    @vitejs/plugin-rsc
    for App Router)
  3. Adds
    "type": "module"
    to package.json
  4. Renames CJS config files (e.g.,
    postcss.config.js
    .cjs
    ) to avoid ESM conflicts
  5. Adds
    dev:vinext
    and
    build:vinext
    scripts to package.json
  6. 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.
运行
vinext init
。该命令会执行以下操作:
  1. 运行
    vinext check
    生成兼容性报告
  2. 安装
    vite
    作为devDependency(若为App Router,还会安装
    @vitejs/plugin-rsc
  3. 向package.json中添加
    "type": "module"
  4. 重命名CJS配置文件(如
    postcss.config.js
    .cjs
    )以避免ESM冲突
  5. 向package.json中添加
    dev:vinext
    build:vinext
    脚本
  6. 生成极简版
    vite.config.ts
此操作不会破坏原有配置——现有Next.js设置可与vinext并行使用。在完全切换前,可使用
dev:vinext
脚本进行测试。
vinext init
执行成功,直接跳至阶段4(验证)。若执行失败或用户偏好手动控制,请继续阶段3。

Phase 3: Manual Migration

阶段3:手动迁移

Use this as a fallback when
vinext init
doesn't work or the user wants full control.
vinext init
无法正常工作或用户希望完全掌控迁移过程时,可使用此方案作为备选。

3a. Replace packages

3a. 替换依赖包

bash
undefined
bash
undefined

Example with npm:

npm示例:

npm uninstall next npm install vinext npm install -D vite
npm uninstall next npm install vinext npm install -D vite

App Router only:

仅App Router需要:

npm install -D @vitejs/plugin-rsc
undefined
npm install -D @vitejs/plugin-rsc
undefined

3b. Update scripts

3b. 更新脚本

Replace all
next
commands in
package.json
scripts:
BeforeAfterNotes
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
.
替换
package.json
脚本中所有
next
命令:
原命令新命令说明
next dev
vinext dev
带HMR的开发服务器
next build
vinext build
生产构建
next start
vinext start
本地生产服务器
next lint
vinext lint
委托给eslint/oxlint执行
保留参数:
next dev --port 3001
vinext dev --port 3001

3c. Convert to ESM

3c. 转换为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
向package.json中添加
"type": "module"
。重命名所有CJS配置文件:
  • postcss.config.js
    postcss.config.cjs
  • tailwind.config.js
    tailwind.config.cjs
  • 其他使用
    module.exports
    .js
    配置文件

3d. Generate vite.config.ts

3d. 生成vite.config.ts

See references/config-examples.md for config variants per router and deployment target.
If the project already has custom Vite config, prefer Vite 8-native keys when editing it:
oxc
,
optimizeDeps.rolldownOptions
, and
build.rolldownOptions
. Older
esbuild
and
build.rollupOptions
settings still work for now but are migration targets.
Pages Router (minimal):
ts
import vinext from "vinext";
import { defineConfig } from "vite";
export default defineConfig({ plugins: [vinext()] });
App Router (minimal):
ts
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.
查看references/config-examples.md获取不同路由及部署目标的配置示例。
若项目已有自定义Vite配置,编辑时优先使用Vite 8原生配置项:
oxc
optimizeDeps.rolldownOptions
build.rolldownOptions
。旧版
esbuild
build.rollupOptions
设置目前仍可使用,但属于待迁移的配置项。
Pages Router(极简版):
ts
import vinext from "vinext";
import { defineConfig } from "vite";
export default defineConfig({ plugins: [vinext()] });
App Router(极简版):
ts
import vinext from "vinext";
import { defineConfig } from "vite";
export default defineConfig({ plugins: [vinext()] });
rsc
选项未显式设置为
false
时,vinext会自动为App Router注册
@vitejs/plugin-rsc
。本地开发无需手动配置RSC插件。

Phase 4: Deployment (Optional)

阶段4:部署(可选)

Option A: Cloudflare Workers (recommended for Cloudflare)

选项A:Cloudflare Workers(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.
若用户希望部署至Cloudflare Workers,使用
vinext deploy
。该命令会自动生成
wrangler.jsonc
、Worker入口文件及缺失的Vite配置,安装
@cloudflare/vite-plugin
wrangler
,然后执行构建与部署。
如需手动设置或自定义Worker入口,请查看references/config-examples.md

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

Cloudflare绑定(D1、R2、KV、AI等)

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:
tsx
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.
要访问Cloudflare绑定(D1、R2、KV、AI、队列、Durable Objects等),可在任意服务器组件、路由处理器或服务器操作中使用
import { env } from "cloudflare:workers"
tsx
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/vite-plugin
在workerd中运行服务器环境,而
cloudflare:workers
是原生模块。无需自定义Worker入口、
getPlatformProxy()
或特殊配置,直接导入即可使用。
绑定需在
wrangler.jsonc
中定义。如需TypeScript类型,运行
wrangler types
重要提示: 请勿使用
getPlatformProxy()
getRequestContext()
或自定义
fetch(request, env)
Worker入口来访问绑定。这些属于旧模式。推荐使用
cloudflare:workers
方式,可与vinext开箱即用。

Option B: Other platforms (via Nitro)

选项B:其他平台(通过Nitro)

For deploying to Vercel, Netlify, AWS, Deno Deploy, or any other Nitro-supported platform, add the Nitro Vite plugin:
bash
npm install nitro
ts
// 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:
bash
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.
如需部署至Vercel、Netlify、AWS、Deno Deploy或其他Nitro支持的平台,添加Nitro Vite插件:
bash
npm install nitro
ts
// vite.config.ts
import { defineConfig } from "vite";
import vinext from "vinext";
import { nitro } from "nitro/vite";

export default defineConfig({
  plugins: [vinext(), nitro()],
});
构建并部署:
bash
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服务器
在大多数CI/CD环境中,Nitro会自动检测平台,因此通常无需指定预设。
注意: 对于Cloudflare Workers,Nitro可正常工作,但原生集成(
vinext deploy
/
@cloudflare/vite-plugin
)提供更好的开发者体验,支持
cloudflare:workers
绑定、KV缓存及一键部署。因此推荐使用原生设置而非Nitro。

Phase 5: Verify

阶段5:验证

  1. Run
    vinext dev
    to start the development server
  2. Confirm the server starts without errors
  3. Navigate key routes and check functionality
  4. Report the result to the user — if errors occur, share full output
See references/troubleshooting.md for common migration errors.
  1. 运行
    vinext dev
    启动开发服务器
  2. 确认服务器无错误启动
  3. 访问关键路由并检查功能
  4. 向用户反馈结果——若出现错误,分享完整输出信息
查看references/troubleshooting.md了解常见迁移错误。

Known Limitations

已知限制

FeatureStatus
next/image
optimization
Remote images via @unpic; no build-time optimization
next/font/google
CDN-loaded, not self-hosted
Domain-based i18nNot supported; path-prefix i18n works
next/jest
Not supported; use Vitest
Turbopack/webpack configIgnored; use Vite plugins instead
runtime
/
preferredRegion
Route segment configs ignored
PPR (Partial Prerendering)Use
"use cache"
directive instead (Next.js 16 approach)
功能状态
next/image
优化
支持通过@unpic处理远程图片;不支持构建时优化
next/font/google
采用CDN加载,不支持自托管
基于域名的国际化(i18n)不支持;路径前缀式国际化可正常使用
next/jest
不支持;请使用Vitest
Turbopack/webpack 配置会被忽略;请使用Vite插件替代
runtime
/
preferredRegion
路由段配置会被忽略
PPR(部分预渲染)请使用
"use cache"
指令替代(Next.js 16方案)

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.
  • 请勿修改
    app/
    pages/
    或应用代码
    。vinext会自动适配所有
    next/*
    导入——无需重写导入路径。
  • 请勿将
    next/*
    导入重写为
    vinext/*
    next/image
    next/link
    next/server
    等导入可自动解析。
  • 请勿将webpack/Turbopack配置复制到Vite配置中。请使用Vite原生插件替代。
  • 请勿跳过兼容性检查。迁移前运行
    vinext check
    可提前发现问题。
  • 请勿删除
    next.config.js
    ,除非用
    next.config.ts
    .mjs
    替代。vinext会读取该文件获取重定向、重写、请求头、basePath、国际化、图片及环境变量配置。
  • 请勿使用
    getPlatformProxy()
    或自定义Worker入口来访问绑定
    。请使用
    import { env } from "cloudflare:workers"
    替代。这是现代方案,可与vinext及
    @cloudflare/vite-plugin
    开箱即用。
  • 对于Cloudflare Workers,优先选择原生集成而非Nitro
    vinext deploy
    /
    @cloudflare/vite-plugin
    提供最佳体验,支持
    cloudflare:workers
    绑定、KV缓存及图片优化。Nitro可用于Cloudflare,但推荐使用原生设置。