1---
2title: Vinext
3description: Deploy vinext to Cloudflare Workers with the shared Website API, native local development, and KV-backed caching.
4sidebar:
5 order: 9.6
6---
7
8import { Code, Tabs, TabItem } from "@astrojs/starlight/components";
9
10export const devDeps = "@alchemy.run/frontend-frameworks";
11
12`Cloudflare.Website.Vinext` builds a [vinext](https://vinext.dev) App Router
13application with Vite and deploys its React Server Components Worker and client
14assets. Alchemy injects its Cloudflare Vite plugin, prerenders routes, and seeds
15the managed KV cache. There is no Wrangler configuration or OpenNext build.
16
17## Install
18
19Keep `vinext`, `react`, `react-dom`, and `react-server-dom-webpack` in your
20application dependencies, and install `vite` and `@vitejs/plugin-rsc` for
21building. Add the Alchemy integration:
22
23<Tabs syncKey="pkgManager">
24 <TabItem label="bun" icon="bun"><Code code={`bun add -d ${devDeps}`} lang="sh" /></TabItem>
25 <TabItem label="npm" icon="npm"><Code code={`npm install -D ${devDeps}`} lang="sh" /></TabItem>
26 <TabItem label="pnpm" icon="pnpm"><Code code={`pnpm add -D ${devDeps}`} lang="sh" /></TabItem>
27 <TabItem label="yarn" icon="seti:yarn"><Code code={`yarn add -D ${devDeps}`} lang="sh" /></TabItem>
28</Tabs>
29
30## Configure vinext
31
32```typescript
33// vite.config.ts
34import { defineConfig } from "vite";
35import vinext from "vinext";
36
37export default defineConfig({
38 plugins: [vinext({ prerender: true })],
39});
40```
41
42Alchemy injects its Cloudflare runtime and KV cache plugins. No Alchemy plugin
43is required in `vite.config.ts`; leave `@cloudflare/vite-plugin` out as well.
44Deployment settings belong on `Cloudflare.Website.Vinext`.
45
46## Declare the Website
47
48```typescript
49// alchemy.run.ts
50import * as Cloudflare from "alchemy/Cloudflare";
51
52export const Website = Cloudflare.Website.Vinext("Website", {
53 rootDir: ".",
54});
55
56export type WebsiteEnv = Cloudflare.InferEnv<typeof Website>;
57```
58
59## Add the Worker entry
60
61The default entry is `worker/index.ts`. Set `main` to use a different path.
62
63```typescript
64// worker/index.ts
65import handler from "vinext/server/fetch-handler";
66import type { WebsiteEnv } from "../alchemy.run";
67
68export default {
69 fetch(request: Request, env: WebsiteEnv, ctx: ExecutionContext) {
70 return handler.fetch(request, env, ctx);
71 },
72};
73```
74
75This Worker entry is Cloudflare-specific. The other platforms generate a
76production server or Lambda entry instead.
77
78## Add it to the Stack
79
80```typescript
81import * as Alchemy from "alchemy";
82import * as Effect from "effect/Effect";
83
84export default Alchemy.Stack(
85 "MyVinextSite",
86 { providers: Cloudflare.providers(), state: Cloudflare.state() },
87 Effect.gen(function* () {
88 const site = yield* Website;
89 return { url: site.url };
90 }),
91);
92```
93
94## Add environment variables
95
96```typescript
97export const Website = Cloudflare.Website.Vinext("Website", {
98 env: { GREETING: "Hello from vinext on Cloudflare!" },
99});
100```
101
102Server components, route handlers, and server actions read bindings through
103`import { env } from "cloudflare:workers"`. Public framework variables can be
104compiled into browser assets; keep secrets out of public keys.
105
106## Configure the data cache
107
108Alchemy provisions `VINEXT_KV_CACHE`, enables Workers Cache, and binds
109`CF_VERSION_METADATA`. Keep these managed bindings out of `env`.
110
111The resource automatically injects the KV adapter for ISR and `"use cache"`. Deployment uploads prerendered HTML and React Server
112Components payloads into KV. During prerendering, where the binding is absent,
113the adapter falls back to memory. Redis and S3 adapters are for other platforms.
114
115## Local development
116
117```sh
118bun alchemy dev
119```
120
121The Website runs the native Vite development server with HMR and local Worker
122bindings. Other resources declared in the Stack retain their own provider
123behavior. Apply `.pipe(Alchemy.remote())` to deploy the Website during development.
124
125## Custom domains
126
127```typescript
128const site = yield* Cloudflare.Website.Vinext("Web", {
129 domain: "app.example.com",
130});
131```
132
133Use a zone managed by your Cloudflare account; see
134[Frontends](/cloudflare/frontend/frontends) for shared Website options.
135
136## Where next
137
138- [vinext API reference](/providers/cloudflare/website/vinext).
139- [Runnable example](https://github.com/alchemy-run/alchemy/tree/main/examples/cloudflare-website-vinext), including server actions, D1, and KV.
140- [vinext on AWS](/aws/frontend/vinext), [Fly](/fly/frontend/vinext),
141 [Hetzner](/hetzner/frontend/vinext), [Railway](/railway/frontend/vinext), and
142 [Prisma](/prisma/frontend/vinext).