Vinext
Cloudflare.Website.Vinext builds a vinext App Router
application with Vite and deploys its React Server Components Worker and client
assets. Alchemy injects its Cloudflare Vite plugin, prerenders routes, and seeds
the managed KV cache. There is no Wrangler configuration or OpenNext build.
Install
Section titled “Install”Keep vinext, react, react-dom, and react-server-dom-webpack in your
application dependencies, and install vite and @vitejs/plugin-rsc for
building. Add the Alchemy integration:
bun add -d @alchemy.run/frontend-frameworksnpm install -D @alchemy.run/frontend-frameworkspnpm add -D @alchemy.run/frontend-frameworksyarn add -D @alchemy.run/frontend-frameworksConfigure vinext
Section titled “Configure vinext”import { defineConfig } from "vite";import vinext from "vinext";
export default defineConfig({ plugins: [vinext({ prerender: true })],});Alchemy injects its Cloudflare runtime and KV cache plugins. No Alchemy plugin
is required in vite.config.ts; leave @cloudflare/vite-plugin out as well.
Deployment settings belong on Cloudflare.Website.Vinext.
Declare the Website
Section titled “Declare the Website”import * as Cloudflare from "alchemy/Cloudflare";
export const Website = Cloudflare.Website.Vinext("Website", { rootDir: ".",});
export type WebsiteEnv = Cloudflare.InferEnv<typeof Website>;Add the Worker entry
Section titled “Add the Worker entry”The default entry is worker/index.ts. Set main to use a different path.
import handler from "vinext/server/fetch-handler";import type { WebsiteEnv } from "../alchemy.run";
export default { fetch(request: Request, env: WebsiteEnv, ctx: ExecutionContext) { return handler.fetch(request, env, ctx); },};This Worker entry is Cloudflare-specific. The other platforms generate a production server or Lambda entry instead.
Add it to the Stack
Section titled “Add it to the Stack”import * as Alchemy from "alchemy";import * as Effect from "effect/Effect";
export default Alchemy.Stack( "MyVinextSite", { providers: Cloudflare.providers(), state: Cloudflare.state() }, Effect.gen(function* () { const site = yield* Website; return { url: site.url }; }),);Add environment variables
Section titled “Add environment variables”export const Website = Cloudflare.Website.Vinext("Website", { env: { GREETING: "Hello from vinext on Cloudflare!" },});Server components, route handlers, and server actions read bindings through
import { env } from "cloudflare:workers". Public framework variables can be
compiled into browser assets; keep secrets out of public keys.
Configure the data cache
Section titled “Configure the data cache”Alchemy provisions VINEXT_KV_CACHE, enables Workers Cache, and binds
CF_VERSION_METADATA. Keep these managed bindings out of env.
The resource automatically injects the KV adapter for ISR and "use cache". Deployment uploads prerendered HTML and React Server
Components payloads into KV. During prerendering, where the binding is absent,
the adapter falls back to memory. Redis and S3 adapters are for other platforms.
Local development
Section titled “Local development”bun alchemy devThe Website runs the native Vite development server with HMR and local Worker
bindings. Other resources declared in the Stack retain their own provider
behavior. Apply .pipe(Alchemy.remote()) to deploy the Website during development.
Custom domains
Section titled “Custom domains”const site = yield* Cloudflare.Website.Vinext("Web", { domain: "app.example.com",});Use a zone managed by your Cloudflare account; see Frontends for shared Website options.
Where next
Section titled “Where next”- vinext API reference.
- Runnable example, including server actions, D1, and KV.
- vinext on AWS, Fly, Hetzner, Railway, and Prisma.