1---
2title: 2.0.0-beta.39 - HTTP Lifecycle & Vite Env
3date: 2026-05-13T18:00:00Z
4category: release
5excerpt: A small, high-impact fix release — `VITE_*` env props are now inlined into the client bundle, the Cloudflare Worker HTTP adapter runs handlers through Effect's standard HTTP lifecycle (unblocking `RpcServer.toHttpEffect`), and the `SendEmail` binding from beta.38 is now wired into Worker binding inference.
6---
7
8`v2.0.0-beta.39` is a fix-only release that lands three
9things people hit immediately after beta.38: SPAs reading
10`import.meta.env.VITE_*`, Effect RPC servers running under
11the Cloudflare Worker adapter, and the brand-new
12`SendEmail` binding showing up in Worker binding types.
13
14## `Cloudflare.Website.Vite` inlines `VITE_*` env into the bundle
15
16`Cloudflare.Website.Vite("Site", { env: { ... } })` was forwarding
17`env` only as runtime Worker bindings — the values never
18made it into the client (or SSR) bundle. SPAs reading
19`import.meta.env.VITE_API_URL` fell back to whatever
20default the code hardcoded, breaking dynamic backend URLs
21at build time.
22
23The build step now passes `props.env` through Vite's
24`define` hook, emulating `vite build`'s env semantics:
25
26```typescript
27const web = yield* Cloudflare.Website.Vite("Web", {
28 env: { VITE_API_URL: worker.url.as<string>() },
29});
30// SPA: `import.meta.env.VITE_API_URL` now contains the deployed worker URL.
31```
32
33The rules match Vite itself:
34
35- Only `VITE_`-prefixed keys are inlined into the bundle
36 as `import.meta.env.<key>` (matches Vite's default
37 `envPrefix`).
38- Non-`VITE_` entries stay out of the bundle but are still
39 attached to the deployed Worker as runtime bindings.
40- `Redacted` values are unwrapped when they're
41 `VITE_`-prefixed — opting them into the public bundle
42 is an explicit choice you make by naming them that way.
43
44The tutorial gains an [Inject the Worker URL at build
45time](/cloudflare/frontend/vite-spa) section covering the
46pattern end-to-end.
47
48## Cloudflare Worker HTTP adapter — Effect's handled lifecycle
49
50The Worker HTTP adapter previously hand-rolled the
51`HttpServerRequest` / `HttpServerResponse` bridge. That
52worked for simple handlers but diverged from Effect's
53`HttpEffect.toHandled` / `toWebHandler` lifecycle in ways
54that broke scoped HTTP apps under workerd — most visibly,
55`RpcServer.toHttpEffect` hung when served through Alchemy
56even though the same app worked under raw Wrangler.
57
58The adapter now runs handlers through Effect's standard
59HTTP lifecycle while preserving every Worker-specific
60behavior:
61
62- `cf-connecting-ip` → `remoteAddress`
63- the original Cloudflare `Request` service
64- patched `request.raw` access
65- existing 500 response mapping from `serveWebRequest`
66
67…plus the parts that were missing: stream-scope transfer,
68HEAD body suppression, and request-abort interruption.
69
70The net effect: anything that worked under
71`@effect/platform`'s standard HTTP lifecycle now works
72under `Cloudflare.Worker` too. `RpcServer.toHttpEffect`,
73in particular, is unblocked.
74
75— *Thanks to **[Will King](https://github.com/wking-io)**
76([#328](https://github.com/alchemy-run/alchemy/pull/328))
77for the fix.* Fixes
78[#327](https://github.com/alchemy-run/alchemy/issues/327).
79
80## `SendEmail` binding type inference
81
82beta.38 added `Cloudflare.Email.SendEmail` but two wiring sites
83in `Worker.ts` were missed — the binding type inference
84didn't know about it, and the deploy-time binding
85metadata didn't emit a `send_email` entry. The result:
86typing `bindings: { EMAIL: Email }` on a Worker errored,
87and deploys silently dropped the binding.
88
89Both are wired up now — `SendEmail` is a first-class
90member of the Worker binding union, the env key carries
91the right runtime type, and Cloudflare receives the
92expected `send_email` binding metadata at deploy time.
93
94— *Thanks to **[Gerben Mulder](https://github.com/Gerbuuun)**
95([#326](https://github.com/alchemy-run/alchemy/pull/326))
96for catching this.*
97
98## Contributors
99
100Big thank-you to everyone who shipped code in this beta:
101
102- **[Will King](https://github.com/wking-io)** — Cloudflare Worker HTTP effect lifecycle ([#328](https://github.com/alchemy-run/alchemy/pull/328))
103- **[Gerben Mulder](https://github.com/Gerbuuun)** — `SendEmail` Worker binding type and meta ([#326](https://github.com/alchemy-run/alchemy/pull/326))
104
105## Where to go next
106
107- [CHANGELOG](https://github.com/alchemy-run/alchemy/blob/main/CHANGELOG.md#v200-beta39)
108- [Compare v2.0.0-beta.38 → v2.0.0-beta.39](https://github.com/alchemy-run/alchemy/compare/v2.0.0-beta.38...v2.0.0-beta.39)