Skip to content

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 Vite
3. phaze-vite ← island HMR + chunking helpers
4. 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.

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.

vite build --app runs two Vite 7 environments in one process:

  • clientdist/client/assets/*.js (hashed browser bundle) + .vite/manifest.json.
  • ssrdist/server/index.js — a single self-contained Worker (inlineDynamicImports: true, everything noExternal), ready for wrangler deploy.

Optional prerender: [...] paths render to static HTML in closeBundle (production builds only).

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 devvite build --app --watch + in-process Miniflare. closeBundle starts (or mf.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-process vite 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).

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.

  • 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 GitHubplugin.ts is the whole adapter (routing, codegen, build config, Miniflare dev runtime) in one file.