Development
The Vite-powered dev loop, build output, and execution model
Commands
bun run dev # vite dev — local dev server on :5173
bun run build # vite build — emits dist/ for Wrangler
bun run deploy # build + wrangler deploy
vite dev uses the Cloudflare Vite plugin under the hood, so local requests hit a Workers-accurate runtime with real DO / KV / D1 bindings.
What the Vite plugin does
The koze() plugin in vite.config.ts is the entire build pipeline. At config time it:
- Discovers routes — every
src/routes/**/*.kozefile becomes a URL pattern. - Auto-maintains
wrangler.jsonc— fields for Durable Objects, containers, sandboxes, queues, pipelines, and assets are kept in sync withsrc/server/*.do.ts,*.workflow.ts,*.queue.ts,*.pipeline.ts,*.sandbox.ts,*.container.ts. - Synthesizes virtual modules —
koze:worker,koze:request,koze:layout,koze:app, and friends materialize at build time. - Extracts client fragments — template-body
<script>blocks become hashed ES modules so Vite's Rollup build can serve + hash them per route. - Resolves
$server/*and$lib/*aliases — env-aware:$server/*resolves to RPC stubs in the client environment and to real files in the SSR environment.
Build output
dist/
├─ ssr/ Worker bundle (Wrangler deploys this)
│ ├─ index.js
│ └─ wrangler.json generated from wrangler.jsonc
└─ client/ hashed client assets
├─ assets/
└─ .vite/manifest.json
.koze/ is legacy CLI output and is not used in Vite projects.
Execution model
Koze is SSR by default:
- Pages render on the server.
- The authored top
<script>on a route is client-first — the compiler runs it server-side for SSR and produces a browser bundle where$server/*imports are rewritten to RPC fetch stubs. - Form
action={fn}POSTs run the server function and return a redirect (POST-Redirect-GET). - Server logic lives in
src/server/*.tsandsrc/middleware.ts.
See Routing for the full route lifecycle.
Mode-aware compilation
Koze bakes the current Vite mode into generated output:
vite dev→import { dev } from 'koze:environment'compiles totrue.vite build→ the same import compiles tofalse.
Use this for development-only branches such as auth bypasses, fixture loading, or verbose logging.
Hot reload caveats
- Route and server file changes hot-reload normally.
- Plugin source changes (
koze/viteitself) require a fullvite devrestart — Vite loads plugins at config time and does not hot-reload them, even from afile:override install.
Production checklist
Before deploying, verify:
src/app.kozeexists (or accept the default shell).src/routes/index.kozeor another entry route exists.wrangler.jsoncmainissrc/worker.ts.bun run buildsucceeds.bun run deploypushes the bundled worker.