In February, Cloudflare published vinext. It’s a Vite plugin that reimplements the public Next.js API surface. File-system routing, server components, server actions, ISR, middleware, the next/* imports. All of it running on Vite instead of Turbopack.
One engineer built it in a week, directing Claude through over 800 sessions in OpenCode. Total cost: about $1,100 in API tokens. The result covers roughly 94% of the Next.js 16 API surface, builds up to 4.4x faster, and produces bundles 57% smaller.
This is not a wrapper around Next.js. It’s a reimplementation. Your Next.js code runs on entirely different tooling.
Why this matters
The self-hosting Next.js problem exists because Next.js is built around Vercel’s infrastructure. OpenNext adapts the Next.js build output for other platforms; vinext throws out the build toolchain entirely and reimplements the API contract on Vite.
The practical effect is the same. You can deploy Next.js apps outside Vercel. But the mechanism is cleaner. Instead of reverse-engineering build artifacts, vinext treats the Next.js API as a specification and implements it from scratch.
Migrating an existing Next.js app
The migration is straightforward. Install vinext, swap the CLI commands, done.
npm install vinext
Update your package.json scripts:
{
"scripts": {
"dev": "vinext dev",
"build": "vinext build",
"start": "vinext start",
"deploy": "vinext deploy"
}
}
Or run npx vinext init to automate it. That handles the dependency installation, config generation, and ESM conversion.
Your next.config.ts is loaded automatically. Your .env files work the same way, including NEXT_PUBLIC_* variables. All 33 next/* imports (next/link, next/image, next/navigation, etc.) are shimmed transparently.
If you want to check compatibility before committing, run:
npx vinext check
What works
The 94% number is real. For most production apps, everything you use daily works:
- App Router and Pages Router. Full support for both, including nested layouts, loading states, error boundaries, parallel routes, and intercepting routes
- Server Components and Server Actions. RSC streaming,
"use server"directives, FormData support - ISR. Stale-while-revalidate caching, backed by Cloudflare KV when deployed to Workers
- Middleware. Request/response interception, rewrites, redirects
- API Routes. Both
pages/apiandapp/apiroute handlers - Metadata API.
generateMetadata, static metadata files,next/ogfor dynamic OG images
What doesn’t
A few things are missing or different:
- Local image optimisation.
next/imageuses Unpic for remote images, but local images fall back to standard<img>tags. No sharp-based resizing. - Google Fonts. No automatic self-hosting or font subsetting via
next/font/google - Partial Prerendering (PPR). Not implemented yet
- Turbopack-specific features. Anything that depends on Turbopack internals rather than the public API
There’s also the security question. Vercel’s security team found seven vulnerabilities in vinext shortly after launch. Two critical, two high severity. These have been addressed, but it’s a reminder that AI-generated code at this scale needs thorough review. Cloudflare has been transparent about the process and the fixes.
The “AI slop” criticism is predictable and partly fair. 800 AI sessions, $1,100 in tokens, no human code review before launch. Seven security vulnerabilities in the first week. But the framing cuts both ways. Most open source projects ship bugs. Most frameworks have CVEs in their first year. The difference here is that people know it was AI-written, so every bug becomes evidence for a narrative. If a human engineer had shipped the same seven vulnerabilities in a week-old project, nobody would have written a headline about it.
The real question isn’t whether AI-generated code has bugs. It does. The question is whether the output is useful enough to justify the approach. 94% API coverage of a complex framework in a week is a rough first draft that needs hardening. That’s true of most v0.x software regardless of who wrote it.
For a demo app or a side project, none of this is a blocker. For a production app handling sensitive data, evaluate the maturity carefully.
Deploy path 1: Cloudflare Workers
This is the primary deployment target. One command:
vinext deploy
This builds your app, generates a wrangler.jsonc configuration, and deploys to Cloudflare Workers. You get:
- Zero cold starts
- Global edge deployment
- ISR backed by Cloudflare KV
- Access to the Cloudflare platform (KV, R2, D1, AI bindings)
For staging or preview environments:
vinext deploy --env staging
vinext deploy --preview
There’s also an experimental traffic-aware pre-rendering mode that analyses your Cloudflare zone analytics to only pre-render high-traffic pages:
vinext deploy --experimental-tpr
Deploy path 2: Docker on a VPS
vinext also works as a standard Node server via vinext start. You can containerise it and run it anywhere, including on a Hetzner VPS with Dokploy, which is what I’ve moved to for personal projects.
The Dockerfile is a standard multi-stage build:
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:22-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./
EXPOSE 3000
CMD ["npm", "run", "start"]
The build step runs vinext build, which produces a dist/ directory with the Vite bundle. The runner copies that bundle plus node_modules and serves it with vinext start.
Deploy with Dokploy the same way as any Docker app: connect the GitHub repo, point at the Dockerfile, set a domain, and Traefik handles SSL.
The ISR cache on a VPS is in-memory by default, so it resets on deploy. For most apps that’s fine. Pages regenerate on the first request. If you need persistent ISR, add a Redis container and configure vinext’s cache handler.
The demo
I migrated a small Next.js app to vinext to verify the claims: server components, a server action (guestbook form), ISR (visitor list that revalidates every 30 seconds), and an API route.
The migration took about two minutes. npm install vinext, change four lines in package.json, vinext build. It worked first try.
The repo is public: github.com/danieljohnmorris/vinext-demo
Where this goes
vinext is experimental software. The 94% coverage is impressive for a week of work, but the remaining 6% and the security surface both need time.
The interesting thing is what this says about the framework market. If the Next.js API can be reimplemented on Vite in a week, the API itself is the valuable part, not the build toolchain. That changes how much Vercel can charge for hosting Next.js as the only first-class option. OpenNext works around the toolchain. vinext replaces it.
For now, I’d use vinext for new projects destined for Cloudflare Workers, and for side projects where the faster builds and smaller bundles are a nice quality-of-life improvement. For production apps on Next.js, OpenNext is still the safer bet. It’s been battle-tested longer and doesn’t rewrite the engine under your code.
But if vinext reaches 1.0 with a clean security audit, it becomes a serious option. A Next.js-compatible framework with 4x faster builds that deploys to both edge and traditional servers.