All skills
cloudflare avatar

/migrate-to-vinext

@115771d
by cloudflarecloudflare/vinext9.1k stars
427

Migrates Next.js projects to vinext (Vite-based Next.js reimplementation). Load when asked to migrate, convert, or switch from Next.js to vinext. Handles compatibility scanning, package replacement, Vite config generation, ESM conversion, and deployment setup (Cloudflare Workers natively, other platforms via Nitro).

Use this Skill: https://skilld.dev/gh/cloudflare/vinext/migrate-to-vinext

This session only. Nothing lands on disk.

referencestroubleshooting.md

≈1.5k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Troubleshooting

Common Migration Errors

Error Cause Fix
ERR_REQUIRE_ESM or require() of ES Module Project missing "type": "module" Add "type": "module" to package.json
module.exports syntax error in config file CJS config loaded as ESM Rename .js config to .cjs (e.g., postcss.config.js → postcss.config.cjs)
Cannot find module '@vitejs/plugin-rsc' App Router project missing RSC plugin npm install -D @vitejs/plugin-rsc
Cannot find module 'vite' Vite not installed npm install -D vite
vinext: command not found vinext not installed or not in PATH Install vinext: npm install vinext, then run via npx vinext or package.json scripts
RSC environment crash on dev start Native Node module (sharp, satori) loaded in RSC env vinext auto-stubs these in production; in dev, ensure these are only imported in server code behind dynamic import()
ASSETS binding not found wrangler.jsonc missing assets config Add "assets": { "not_found_handling": "none" } to wrangler.jsonc

Vite 8 Migration Notes

  • Symptom: deprecation warnings for esbuild, optimizeDeps.esbuildOptions, or build.rollupOptions. Cause: Vite 8 now defaults to Oxc and Rolldown. Fix: Prefer oxc, optimizeDeps.rolldownOptions, and build.rolldownOptions / worker.rolldownOptions in custom Vite config.

  • Symptom: a package only breaks on Vite 8 with a bad default import from CommonJS. Cause: Vite 8 made CommonJS default import handling more consistent. Fix: Fix the import or package if possible. As a temporary workaround, set legacy.inconsistentCjsInterop: true.

  • Symptom: older browsers stop working after migration. Cause: Vite 8 raised the default build.target browser baseline. Fix: Set build.target explicitly in vite.config.* if you need older browser support.

ESM Conversion Issues

When adding "type": "module", any .js file using module.exports or require() will break. Common files that need renaming to .cjs:

  • postcss.config.js
  • tailwind.config.js
  • .eslintrc.js
  • jest.config.js (if kept alongside Vitest)
  • prettier.config.js

Alternatively, convert these files to ESM (export default syntax) and keep the .js extension.

Third-Party Package ESM Resolution Errors

Symptom: Cannot find module '...' errors in dev server when using certain npm packages.

Example Error:

Cannot find module '\node_modules.pnpm\validator@13.15.26\node_modules\validator\es\lib\util\assertString'
imported from \node_modules.pnpm\validator@13.15.26\node_modules\validator\es\lib\isEmail.js

Cause: Some ESM packages have complex internal import structures that Node.js module resolution can't handle when externalized.

vinext Fix: vinext sets noExternal: true in all server environments (RSC and SSR), which forces all dependencies through Vite's transform pipeline. This resolves extensionless import issues automatically.

No configuration needed — this is the default behavior.

App Router vs Pages Router Issues

Symptom: RSC-related errors, "client/server component" boundary violations. Cause: App Router requires @vitejs/plugin-rsc for React Server Components. Fix: vinext auto-registers this plugin when it detects app/. If auto-registration is disabled (rsc: false), enable it or add the plugin manually. See config-examples.md.

Symptom: getServerSideProps / getStaticProps not executing. Cause: These are Pages Router APIs. They only work in pages/, not app/. Fix: This is expected Next.js behavior, not a vinext issue.

Cloudflare Deployment Issues

Symptom: Build succeeds but deploy fails with worker size errors. Cause: Bundle too large for Workers free tier (1 MB) or paid tier (10 MB). Fix: Check for large dependencies. Use npx vite build and inspect output size. Consider code splitting or moving large deps to external services.

Symptom: Image optimization returns 404 or broken images. Cause: Missing Cloudflare Images binding. Fix: Add "images": { "binding": "IMAGES" } and "assets": { "binding": "ASSETS" } to wrangler.jsonc.

Symptom: ISR pages not caching across requests. Cause: Default MemoryCacheHandler doesn't persist across Worker invocations. Fix: Use KVCacheHandler from vinext/cloudflare with a KV namespace binding. See config-examples.md.

Verification Checklist

After migration, confirm:

  • npx vite dev starts without errors
  • Home page renders correctly
  • Dynamic routes resolve (e.g., /posts/[id])
  • API routes respond (Pages Router) or route handlers respond (App Router)
  • Client-side navigation works (Link component)
  • Static assets load (images, fonts, CSS)
  • Environment variables (NEXT_PUBLIC_*) are available
  • Middleware or proxy.ts executes on matching routes

Source: SKILL.md on GitHub

No alerts3d5 checks · Risk SAFE
  • Gen Agent Trust Hub3d

    This skill provides a guided process for migrating web projects to a new build system and framework. It utilizes standard developer workflows, including automated package management and command execution for building and deploying applications. These operations are appropriate for the skill's stated purpose of project migration.

  • Socket3d

    No alerts

  • Snyk3d

    Risk: LOW · No issues

  • Runlayer6mo

    4 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 115771d. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 hours ago.

Activeupdated 3 days ago
  • Next.js
  • vite
  • vinext
  • migration
  • cloudflare
  • workers
  • esm
  • app-router
  • pages-router
  • nitro

README badge

README badge for cloudflare/vinext

Migrates Next.js projects to vinext, a Vite-based reimplementation of Next.js that runs existing app/ and pages/ directories without code changes. Handles compatibility scanning, package replacement, Vite config generation, ESM conversion, and deployment to Cloudflare Workers or other platforms via Nitro.

Generated from the current SKILL.md.

Do I need to rewrite my app/ or pages/ directory?
No. vinext reimplements the Next.js API surface on Vite, so existing `app/`, `pages/`, and `next.config.js` work as-is without code changes.
What package managers does this support?
The skill detects and works with npm, pnpm, yarn, and bun based on the lockfile present in the project.
Can I deploy to platforms other than Cloudflare?
Yes. For Vercel, Netlify, AWS, Deno Deploy, and other platforms, add the Nitro Vite plugin and set the appropriate NITRO_PRESET during build. For Cloudflare Workers specifically, the native `vinext deploy` integration is recommended.
How do I access Cloudflare bindings like D1, R2, or KV?
Use `import { env } from "cloudflare:workers"` in server components or route handlers. Bindings must be defined in `wrangler.jsonc`, and this approach works out of the box with vinext and `@cloudflare/vite-plugin`.
What happens if vinext init fails?
The skill provides a manual migration path (Phase 3) that covers package replacement, script updates, ESM conversion, and Vite config generation as a fallback.

Generated from the current SKILL.md. These answers refresh after source changes.