Skip to content

Vite

Source: src/Cloudflare/Website/Vite.ts

A Cloudflare Worker deployed from a Vite project.

Vite uses the Cloudflare Vite plugin to build both the server bundle and client assets in a single vite build invocation — no manual main entrypoint, build command, output directory, or Wrangler configuration required.

Input files are content-hashed (respecting .gitignore by default) so unchanged projects skip the build and deploy entirely.

For a pure static site (no SSR), a single call is all you need. Vite builds the project and Alchemy deploys the output as a Cloudflare Worker with static assets.

const site = yield* Cloudflare.Website.Vite("Website");

For SSR frameworks like TanStack Start or SolidStart, enable nodejs_compat so the server bundle can use Node.js APIs.

TanStack Start

const app = yield* Cloudflare.Website.Vite("TanStackStart", {
compatibility: {
flags: ["nodejs_compat"],
},
});

SolidStart with worker-first routing

const app = yield* Cloudflare.Website.Vite("SolidStart", {
compatibility: {
flags: ["nodejs_compat"],
},
assets: { runWorkerFirst: true },
});

Frameworks that emit more than one server environment (e.g. React Server Components, which split into an rsc environment and an ssr environment) need viteEnvironments to declare which environment produces the deployed Worker entry and which additional server environments to bundle alongside it. The client environment is always deployed as static assets.

const app = yield* Cloudflare.Website.Vite("ReactRouterRSC", {
compatibility: {
flags: ["nodejs_compat"],
},
viteEnvironments: {
entry: "rsc",
children: ["ssr"],
},
});

By default the deployed Worker entry is the server bundle the framework produces. When the Worker must export more than the framework’s fetch handler — Durable Object classes, additional handlers — point main at your own module that wraps the framework handler and re-exports the extras. main takes precedence over any entry configured in the Vite config.

const app = yield* Cloudflare.Website.Vite("App", {
main: "worker/index.ts",
viteEnvironments: {
entry: "rsc",
children: ["ssr"],
},
});

For SPAs (React, Vue, etc.), configure asset handling so all routes fall back to index.html.

const app = yield* Cloudflare.Website.Vite("Vue", {
compatibility: {
flags: ["nodejs_compat"],
},
assets: {
htmlHandling: "auto-trailing-slash",
notFoundHandling: "single-page-application",
},
});

By default, every non-gitignored file is hashed to decide whether a rebuild is needed. Use memo to narrow the scope when your project has large directories that don’t affect the build output.

const site = yield* Cloudflare.Website.Vite("Docs", {
memo: {
include: ["src/**", "content/**", "package.json"],
},
});

Calling Vite with no arguments returns a constructor you can extend to declare the Worker as a named class. The class is both an Effect you can yield* to deploy and a type you can reference elsewhere — useful when other resources need to bind to this Worker.

class Website extends Cloudflare.Website.Vite<Website>()("Website", {
compatibility: { flags: ["nodejs_compat"] },
}) {}
const site = yield* Website;