vinext 0.0.18 → 0.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +137 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -106,7 +106,7 @@ Vite has become the default build tool for modern web frameworks — fast HMR, a
|
|
|
106
106
|
|
|
107
107
|
vinext is an experiment: can we reimplement the Next.js API surface on Vite, so that existing Next.js applications can run on a completely different toolchain? The answer, so far, is mostly yes — about 94% of the API surface works.
|
|
108
108
|
|
|
109
|
-
|
|
109
|
+
vinext works everywhere. It natively supports Cloudflare Workers (with `vinext deploy`, bindings, KV caching), and can be deployed to Vercel, Netlify, AWS, Deno Deploy, and more via the [Nitro](https://v3.nitro.build/) Vite plugin. Native support for additional platforms is [planned](https://github.com/cloudflare/vinext/issues/80).
|
|
110
110
|
|
|
111
111
|
**Alternatives worth knowing about:**
|
|
112
112
|
- **[OpenNext](https://opennext.js.org/)** — adapts `next build` output for AWS, Cloudflare, and other platforms. OpenNext has been around much longer than vinext, is more mature, and covers more of the Next.js API surface because it builds on top of Next.js's own output rather than reimplementing it. If you want the safer, more proven option, start there.
|
|
@@ -114,7 +114,7 @@ The current deployment target is Cloudflare Workers — zero cold starts, global
|
|
|
114
114
|
|
|
115
115
|
### Design principles
|
|
116
116
|
|
|
117
|
-
- **
|
|
117
|
+
- **Deploy anywhere.** Natively supports Cloudflare Workers, with other platforms available via Nitro. Native adapters for more platforms are [planned](https://github.com/cloudflare/vinext/issues/80).
|
|
118
118
|
- **Pragmatic compatibility, not bug-for-bug parity.** Targets 95%+ of real-world Next.js apps. Edge cases that depend on undocumented Vercel behavior are intentionally not supported.
|
|
119
119
|
- **Latest Next.js only.** Targets Next.js 16.x. No support for deprecated APIs from older versions.
|
|
120
120
|
- **Incremental adoption.** Drop in the plugin, fix what breaks, deploy.
|
|
@@ -122,7 +122,7 @@ The current deployment target is Cloudflare Workers — zero cold starts, global
|
|
|
122
122
|
## FAQ
|
|
123
123
|
|
|
124
124
|
**What is this?**
|
|
125
|
-
vinext is a Vite plugin that reimplements the public Next.js API — routing, server rendering, `next/*` module imports, the CLI — so you can run Next.js applications on Vite instead of the Next.js compiler toolchain. Cloudflare Workers is the
|
|
125
|
+
vinext is a Vite plugin that reimplements the public Next.js API — routing, server rendering, `next/*` module imports, the CLI — so you can run Next.js applications on Vite instead of the Next.js compiler toolchain. It can be deployed anywhere: Cloudflare Workers is the first natively supported target, with other platforms available via Nitro. Native adapters for more platforms are [planned](https://github.com/cloudflare/vinext/issues/80).
|
|
126
126
|
|
|
127
127
|
**Is this a fork of Next.js?**
|
|
128
128
|
No. vinext is an alternative implementation of the Next.js API surface built on Vite. It does import some Next.js types and utilities, but the core is written from scratch. The goal is not to create a competing framework or add features beyond what Next.js offers — it's an experiment in how far AI-driven development and Vite's toolchain can go in replicating an existing, well-defined API surface.
|
|
@@ -152,14 +152,18 @@ Both. File-system routing, SSR, client hydration, and deployment to Cloudflare W
|
|
|
152
152
|
Next.js 16.x. No support for deprecated APIs from older versions.
|
|
153
153
|
|
|
154
154
|
**Can I deploy to AWS/Netlify/other platforms?**
|
|
155
|
-
|
|
155
|
+
Yes. Add the [Nitro](https://v3.nitro.build/) Vite plugin alongside vinext, and you can deploy to Vercel, Netlify, AWS Amplify, Deno Deploy, Azure, and [many more](https://v3.nitro.build/deploy). See [Other platforms (via Nitro)](#other-platforms-via-nitro) for setup. For Cloudflare Workers, the native integration (`vinext deploy`) gives you the smoothest experience. Native adapters for more platforms are [planned](https://github.com/cloudflare/vinext/issues/80).
|
|
156
156
|
|
|
157
157
|
**What happens when Next.js releases a new feature?**
|
|
158
158
|
We track the public Next.js API surface and add support for new stable features. Experimental or unstable Next.js features are lower priority. The plan is to add commit-level tracking of the Next.js repo so we can stay current as new versions are released.
|
|
159
159
|
|
|
160
|
-
##
|
|
160
|
+
## Deployment
|
|
161
161
|
|
|
162
|
-
|
|
162
|
+
### Cloudflare Workers
|
|
163
|
+
|
|
164
|
+
vinext has native integration with Cloudflare Workers through `@cloudflare/vite-plugin`, including bindings access via `cloudflare:workers`, KV caching, image optimization, and the `vinext deploy` one-command workflow.
|
|
165
|
+
|
|
166
|
+
`vinext deploy` auto-generates the necessary configuration files (`vite.config.ts`, `wrangler.jsonc`, `worker/index.ts`) if they don't exist, builds the application, and deploys to Workers.
|
|
163
167
|
|
|
164
168
|
```bash
|
|
165
169
|
vinext deploy
|
|
@@ -175,9 +179,40 @@ The deploy command also auto-detects and fixes common migration issues:
|
|
|
175
179
|
- Renames CJS config files (postcss.config.js, etc.) to `.cjs` when needed
|
|
176
180
|
- Detects native Node.js modules (sharp, resvg, satori, lightningcss, @napi-rs/canvas) and auto-stubs them for Workers. If you encounter others that need stubbing, PRs are welcome.
|
|
177
181
|
|
|
178
|
-
Both App Router and Pages Router work on Workers with full client-side hydration
|
|
182
|
+
Both App Router and Pages Router work on Workers with full client-side hydration.
|
|
183
|
+
|
|
184
|
+
#### Cloudflare Bindings (D1, R2, KV, AI, etc.)
|
|
185
|
+
|
|
186
|
+
Use `import { env } from "cloudflare:workers"` to access bindings in any server component, route handler, or server action. No custom worker entry or special configuration required.
|
|
187
|
+
|
|
188
|
+
```tsx
|
|
189
|
+
import { env } from "cloudflare:workers";
|
|
190
|
+
|
|
191
|
+
export default async function Page() {
|
|
192
|
+
const result = await env.DB.prepare("SELECT * FROM posts").all();
|
|
193
|
+
return <div>{JSON.stringify(result)}</div>;
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
This works because `@cloudflare/vite-plugin` runs the RSC environment in workerd, where `cloudflare:workers` is a native module. In production builds, the import is externalized so workerd resolves it at runtime. All binding types are supported: D1, R2, KV, Durable Objects, AI, Queues, Vectorize, Browser Rendering, etc.
|
|
198
|
+
|
|
199
|
+
Define your bindings in `wrangler.jsonc` as usual:
|
|
179
200
|
|
|
180
|
-
|
|
201
|
+
```jsonc
|
|
202
|
+
{
|
|
203
|
+
"name": "my-app",
|
|
204
|
+
"compatibility_date": "2026-02-12",
|
|
205
|
+
"compatibility_flags": ["nodejs_compat"],
|
|
206
|
+
"d1_databases": [{ "binding": "DB", "database_name": "my-db", "database_id": "..." }],
|
|
207
|
+
"kv_namespaces": [{ "binding": "CACHE", "id": "..." }]
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
For TypeScript types, generate them with `wrangler types` and the `env` import will be fully typed.
|
|
212
|
+
|
|
213
|
+
> **Note:** You do not need `getPlatformProxy()`, a custom worker entry with `fetch(request, env)`, or any other workaround. `cloudflare:workers` is the recommended way to access bindings in vinext.
|
|
214
|
+
|
|
215
|
+
#### Traffic-aware Pre-Rendering (experimental)
|
|
181
216
|
|
|
182
217
|
TPR queries Cloudflare zone analytics at deploy time to find which pages actually get traffic, pre-renders only those, and uploads them to KV cache. The result is SSG-level latency for popular pages without pre-rendering your entire site.
|
|
183
218
|
|
|
@@ -199,7 +234,7 @@ import { setCacheHandler } from "next/cache";
|
|
|
199
234
|
setCacheHandler(new KVCacheHandler(env.MY_KV_NAMESPACE));
|
|
200
235
|
```
|
|
201
236
|
|
|
202
|
-
|
|
237
|
+
#### Custom Vite configuration
|
|
203
238
|
|
|
204
239
|
If you need to customize the Vite config, create a `vite.config.ts`. vinext will merge its config with yours. This is required for Cloudflare Workers deployment with the App Router (RSC needs explicit plugin configuration):
|
|
205
240
|
|
|
@@ -228,6 +263,98 @@ export default defineConfig({
|
|
|
228
263
|
|
|
229
264
|
See the [examples](#live-examples) for complete working configurations.
|
|
230
265
|
|
|
266
|
+
### Other platforms (via Nitro)
|
|
267
|
+
|
|
268
|
+
For deploying to platforms other than Cloudflare, vinext works with [Nitro](https://v3.nitro.build/) as a Vite plugin. Add `nitro` alongside `vinext` in your Vite config and deploy to any [Nitro-supported platform](https://v3.nitro.build/deploy).
|
|
269
|
+
|
|
270
|
+
```ts
|
|
271
|
+
import { defineConfig } from "vite";
|
|
272
|
+
import vinext from "vinext";
|
|
273
|
+
import { nitro } from "nitro/vite";
|
|
274
|
+
|
|
275
|
+
export default defineConfig({
|
|
276
|
+
plugins: [vinext(), nitro()],
|
|
277
|
+
});
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
npm install nitro
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Nitro auto-detects the deployment platform in most CI/CD environments (Vercel, Netlify, AWS Amplify, Azure, and others), so you typically don't need to set a preset. For local builds, set the `NITRO_PRESET` environment variable:
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
NITRO_PRESET=vercel npx vite build
|
|
288
|
+
NITRO_PRESET=netlify npx vite build
|
|
289
|
+
NITRO_PRESET=deno_deploy npx vite build
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
> **Deploying to Cloudflare?** You can use Nitro, but the native integration (`vinext deploy` / `@cloudflare/vite-plugin`) is recommended. It provides the best developer experience with `cloudflare:workers` bindings, KV caching, image optimization, and one-command deploys.
|
|
293
|
+
|
|
294
|
+
<details>
|
|
295
|
+
<summary>Vercel</summary>
|
|
296
|
+
|
|
297
|
+
Nitro auto-detects Vercel in CI. For local builds:
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
NITRO_PRESET=vercel npx vite build
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
Deploy with the [Vercel CLI](https://vercel.com/docs/cli) or connect your Git repo in the Vercel dashboard. Set the build command to `vite build` and the output directory to `.output`.
|
|
304
|
+
|
|
305
|
+
</details>
|
|
306
|
+
|
|
307
|
+
<details>
|
|
308
|
+
<summary>Netlify</summary>
|
|
309
|
+
|
|
310
|
+
Nitro auto-detects Netlify in CI. For local builds:
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
NITRO_PRESET=netlify npx vite build
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
Deploy with the [Netlify CLI](https://docs.netlify.com/cli/get-started/) or connect your Git repo. Set the build command to `vite build`.
|
|
317
|
+
|
|
318
|
+
</details>
|
|
319
|
+
|
|
320
|
+
<details>
|
|
321
|
+
<summary>AWS (Amplify)</summary>
|
|
322
|
+
|
|
323
|
+
Nitro auto-detects AWS Amplify in CI. For local builds:
|
|
324
|
+
|
|
325
|
+
```bash
|
|
326
|
+
NITRO_PRESET=aws_amplify npx vite build
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Connect your Git repo in the AWS Amplify console. Set the build command to `vite build`.
|
|
330
|
+
|
|
331
|
+
</details>
|
|
332
|
+
|
|
333
|
+
<details>
|
|
334
|
+
<summary>Deno Deploy</summary>
|
|
335
|
+
|
|
336
|
+
```bash
|
|
337
|
+
NITRO_PRESET=deno_deploy npx vite build
|
|
338
|
+
cd .output
|
|
339
|
+
deployctl deploy --project=my-project server/index.ts
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
</details>
|
|
343
|
+
|
|
344
|
+
<details>
|
|
345
|
+
<summary>Node.js server</summary>
|
|
346
|
+
|
|
347
|
+
```bash
|
|
348
|
+
NITRO_PRESET=node npx vite build
|
|
349
|
+
node .output/server/index.mjs
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
This produces a standalone Node.js server. Suitable for Docker, VMs, or any environment that can run Node.
|
|
353
|
+
|
|
354
|
+
</details>
|
|
355
|
+
|
|
356
|
+
See the [Nitro deployment docs](https://v3.nitro.build/deploy) for the full list of supported platforms and provider-specific configuration.
|
|
357
|
+
|
|
231
358
|
## Live examples
|
|
232
359
|
|
|
233
360
|
These are deployed to Cloudflare Workers and updated on every push to `main`:
|
|
@@ -241,6 +368,7 @@ These are deployed to Cloudflare Workers and updated on every push to `main`:
|
|
|
241
368
|
| Pages Router (minimal) | Minimal Pages Router on Workers | [pages-router-cloudflare.vinext.workers.dev](https://pages-router-cloudflare.vinext.workers.dev) |
|
|
242
369
|
| RealWorld API | REST API routes example | [realworld-api-rest.vinext.workers.dev](https://realworld-api-rest.vinext.workers.dev) |
|
|
243
370
|
| Benchmarks Dashboard | Build performance tracking over time (D1-backed) | [benchmarks.vinext.workers.dev](https://benchmarks.vinext.workers.dev) |
|
|
371
|
+
| App Router + Nitro | App Router deployed via Nitro (multi-platform) | [examples/app-router-nitro](examples/app-router-nitro) |
|
|
244
372
|
|
|
245
373
|
## API coverage
|
|
246
374
|
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAA6B,MAAM,MAAM,CAAC;AAmH9D;;;;;;;;GAQG;AACH,iBAAS,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAkBnF;AAuGD;;;;;;;;;;;GAWG;AACH,iBAAe,2BAA2B,CACxC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,OAAO,EAAE,GAAG,EAAE,CAAA;CAAE,GAAG,SAAS,CAAC,CAqEzC;AA0CD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,iBAAS,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CA8B1D;AAED;;;;;;;;GAQG;AACH,QAAA,MAAM,kBAAkB;;;CAGvB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,QAAA,MAAM,qBAAqB;;;CAG1B,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,iBAAS,iBAAiB,CACxB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;CAChB,CAAC,GACD,MAAM,EAAE,CAwDV;AAED,MAAM,WAAW,aAAa;IAC5B;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAA6B,MAAM,MAAM,CAAC;AAmH9D;;;;;;;;GAQG;AACH,iBAAS,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAkBnF;AAuGD;;;;;;;;;;;GAWG;AACH,iBAAe,2BAA2B,CACxC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,OAAO,EAAE,GAAG,EAAE,CAAA;CAAE,GAAG,SAAS,CAAC,CAqEzC;AA0CD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,iBAAS,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CA8B1D;AAED;;;;;;;;GAQG;AACH,QAAA,MAAM,kBAAkB;;;CAGvB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,QAAA,MAAM,qBAAqB;;;CAG1B,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,iBAAS,iBAAiB,CACxB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;CAChB,CAAC,GACD,MAAM,EAAE,CAwDV;AAED,MAAM,WAAW,aAAa;IAC5B;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,MAAM,EAAE,CAsqFpE;AAoCD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAuG/B;AA8KD,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC9E,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAGhH,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,CAAC;AAC5F,OAAO,EAAE,2BAA2B,IAAI,4BAA4B,EAAE,CAAC;AACvE,OAAO,EAAE,wBAAwB,IAAI,yBAAyB,EAAE,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2115,12 +2115,32 @@ hydrate();
|
|
|
2115
2115
|
configureServer(server) {
|
|
2116
2116
|
// Watch pages directory for file additions/removals to invalidate route cache.
|
|
2117
2117
|
const pageExtensions = /\.(tsx?|jsx?|mdx)$/;
|
|
2118
|
+
/**
|
|
2119
|
+
* Invalidate the virtual RSC entry module in Vite's module graph.
|
|
2120
|
+
*
|
|
2121
|
+
* The App Router route table is baked into the virtual RSC entry
|
|
2122
|
+
* at generation time. When routes are added or removed, clearing
|
|
2123
|
+
* the route cache alone is not enough: the virtual module must
|
|
2124
|
+
* also be invalidated so Vite re-calls the load() hook to
|
|
2125
|
+
* regenerate the entry with the updated route table.
|
|
2126
|
+
*/
|
|
2127
|
+
function invalidateRscEntryModule() {
|
|
2128
|
+
const rscEnv = server.environments["rsc"];
|
|
2129
|
+
if (!rscEnv)
|
|
2130
|
+
return;
|
|
2131
|
+
const mod = rscEnv.moduleGraph.getModuleById(RESOLVED_RSC_ENTRY);
|
|
2132
|
+
if (mod) {
|
|
2133
|
+
rscEnv.moduleGraph.invalidateModule(mod);
|
|
2134
|
+
rscEnv.hot.send({ type: "full-reload" });
|
|
2135
|
+
}
|
|
2136
|
+
}
|
|
2118
2137
|
server.watcher.on("add", (filePath) => {
|
|
2119
2138
|
if (hasPagesDir && filePath.startsWith(pagesDir) && pageExtensions.test(filePath)) {
|
|
2120
2139
|
invalidateRouteCache(pagesDir);
|
|
2121
2140
|
}
|
|
2122
2141
|
if (hasAppDir && filePath.startsWith(appDir) && pageExtensions.test(filePath)) {
|
|
2123
2142
|
invalidateAppRouteCache();
|
|
2143
|
+
invalidateRscEntryModule();
|
|
2124
2144
|
}
|
|
2125
2145
|
});
|
|
2126
2146
|
server.watcher.on("unlink", (filePath) => {
|
|
@@ -2129,6 +2149,7 @@ hydrate();
|
|
|
2129
2149
|
}
|
|
2130
2150
|
if (hasAppDir && filePath.startsWith(appDir) && pageExtensions.test(filePath)) {
|
|
2131
2151
|
invalidateAppRouteCache();
|
|
2152
|
+
invalidateRscEntryModule();
|
|
2132
2153
|
}
|
|
2133
2154
|
});
|
|
2134
2155
|
// Run instrumentation.ts register() if present (once at server startup)
|