5. phaze-cloudflare
1. phaze-tsplugin ← editor (TS Language Service)2. phaze-compile ← build-time AST rewriting ├── babel-plugin.ts ← the actual Babel plugin (all the visitors live here) └── vite-plugin.ts ← thin wrapper that adapts it for Vite3. phaze-vite ← island HMR + chunking helpers4. phaze-astro ← Astro integration (island model)5. phaze-cloudflare ← native Cloudflare Workers adapter (whole-page) ← you are here@madenowhere/phaze-cloudflare is the native Cloudflare Workers adapter — the alternative to phaze-astro (#4) when your deployment target is Workers and you don’t want an Astro layer. You install it instead of phaze-astro (you pick one host adapter per app); both are build-time only — neither grows the sub-3 KB phaze runtime chunk that ships to the browser.
Where phaze-astro is islands (<Component client:load/> mounts independently), phaze-cloudflare is whole-page: the entire page SSRs and hydrates as one reactive tree. The full feature surface (routing, actions, middleware, env, cookies, prefetch, ISR, …) lives in Phaze + Cloudflare; this page is the tooling view — what the package is and how it plugs into Vite.
One Vite plugin
Section titled “One Vite plugin”The consumer’s vite.config.ts needs a single import:
import cloudflare from '@madenowhere/phaze-cloudflare/vite'
export default defineConfig({ plugins: [cloudflare({ pages: 'src/pages', prerender: ['/', '/about'] })],})cloudflare() returns a Vite plugin array. For builds it is [phazeCompile(), main] — it bundles phaze-compile so you don’t wire it yourself. In serve mode it additionally composes @cloudflare/vite-plugin plus a cf-imports / cf-externals pair (see the dev modes below). You don’t add phazeVite(): its per-component replace() HMR is the island model, and phaze-cloudflare’s whole-page hydration has no per-island boundary to target (its dev HMR works differently — below). phazeChunks() is applied internally to both build environments.
The plugin owns: file-system routing under src/pages, the virtual server/client entries (__phaze/server / __phaze/client), ambient env/action type-gen (.phaze/types.d.ts), server-entry codegen, the dual-environment build, and the dev runtime.
The dual-environment build
Section titled “The dual-environment build”vite build --app runs two Vite 7 environments in one process:
client→dist/client/assets/*.js(hashed browser bundle) +.vite/manifest.json.ssr→dist/server/index.js— a single self-contained Worker (inlineDynamicImports: true, everythingnoExternal), ready forwrangler deploy.
Optional prerender: [...] paths render to static HTML in closeBundle (production builds only).
Two dev modes — both real workerd
Section titled “Two dev modes — both real workerd”Unlike Astro’s single dev server, phaze-cloudflare offers two single-process dev loops, both serving real workerd with real bindings (D1 / KV / R2 / cloudflare:sockets, .dev.vars secrets, shared .wrangler/state/v3):
pnpm dev→vite build --app --watch+ in-process Miniflare.closeBundlestarts (ormf.setOptions-hot-swaps) an in-process Miniflare against the freshly built worker. Full reload per rebuild (~200–1500 ms), build-grade output (real CSS<link>s, shaped assets, the size report). Replaces the old two-processvite build --watch+wrangler dev.pnpm dev:hmr→ a Vite dev server. Serve mode composes@cloudflare/vite-plugin, so the worker runs inside Miniflare via Vite 7’s Environment-API module runner — real workerd and live module updates. The client gets true HMR (import.meta.hot); phaze adds Tier-1 page-level HMR by making the client entry the accept boundary (App-subtree edits re-render the root, page edits swap the active page reactively).
Why it’s separate from phaze-astro
Section titled “Why it’s separate from phaze-astro”Same reasoning as the rest of the stack: different host, different deps. phaze-astro plugs into Astro’s integration API and pulls in Astro’s types; phaze-cloudflare plugs straight into Vite and pulls in @cloudflare/vite-plugin, miniflare, and wrangler. An Astro app never installs miniflare/wrangler; a Cloudflare app never installs Astro. Keeping them as distinct packages (#4 and #5) means each app’s dependency tree carries only its target’s host glue — and, since both are build-time, neither affects the shipped runtime byte budget.
Where to go from here
Section titled “Where to go from here”- Phaze + Cloudflare — the full adapter surface: routing, actions, middleware, env, cookies, prefetch, client router, ISR, the two dev modes in depth, and the native-vs-Astro performance comparison.
- phaze-cloudflare source on GitHub —
plugin.tsis the whole adapter (routing, codegen, build config, Miniflare dev runtime) in one file.