<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>alchemy | Blog</title><description/><link>https://v2.alchemy.run/</link><language>en</language><item><title>alchemy@2.0.0-beta.40</title><link>https://v2.alchemy.run/blog/2026-05-15-beta-40/</link><guid isPermaLink="true">https://v2.alchemy.run/blog/2026-05-15-beta-40/</guid><description>Cloudflare local dev gains a real Vite dev server (HMR, SSR, client + worker in one process), AiGateway stops reporting spurious updates on every deploy, the Worker HTTP server returns generic 500s while logging the full Cause server-side, and a handful of fixes around entrypoint generation, container startup, and the dev lockfile.

</description><pubDate>Fri, 15 May 2026 22:00:00 GMT</pubDate><content:encoded>&lt;aside aria-label=&quot;Caution&quot;&gt;&lt;p aria-hidden=&quot;true&quot;&gt;Caution&lt;/p&gt;&lt;div&gt;&lt;p&gt;&lt;strong&gt;Upgrade immediately if you’re on beta.39.&lt;/strong&gt; This release
reverts a critical bug introduced in beta.39 where
&lt;code dir=&quot;auto&quot;&gt;scopeTransferToStream&lt;/code&gt; caused &lt;strong&gt;415&lt;/strong&gt; responses from
Workers and &lt;strong&gt;500&lt;/strong&gt; errors against the Cloudflare state
store. The state store version has also been bumped to
&lt;strong&gt;v5&lt;/strong&gt; — older clients will refuse to load mismatched
state and prompt you to upgrade.&lt;/p&gt;&lt;/div&gt;&lt;/aside&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;v2.0.0-beta.40&lt;/code&gt; is headlined by a real Vite dev server
for Cloudflare Workers — &lt;code dir=&quot;auto&quot;&gt;Cloudflare.Vite&lt;/code&gt; now boots a
single process that serves your client, SSR, and Worker
through Vite, with HMR. The rest of the release is fixes
that quiet noisy diffs, tighten error responses, and
harden codegen against odd file paths.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;cloudflarevite--real-vite-dev-server&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;Cloudflare.Vite&lt;/code&gt; — real Vite dev server&lt;/h2&gt;&lt;a href=&quot;#cloudflarevite--real-vite-dev-server&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Cloudflare.Vite — real Vite dev server”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;bun alchemy dev&lt;/code&gt; for a &lt;code dir=&quot;auto&quot;&gt;Cloudflare.Vite&lt;/code&gt; resource
previously bundled the Worker and served the built output
through the sidecar. That worked, but it skipped the part
of the Vite toolchain people actually want during
development: HMR, on-demand SSR, the client/SSR/worker
environments wired together.&lt;/p&gt;
&lt;p&gt;beta.40 replaces that with &lt;code dir=&quot;auto&quot;&gt;vite.createServer&lt;/code&gt; driven
through &lt;code dir=&quot;auto&quot;&gt;@distilled.cloud/cloudflare-vite-plugin&lt;/code&gt;. The
sidecar now hosts a Vite dev server that serves your
client and SSR, while the Worker runs in the same process
against the live module graph:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;web&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Vite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Web&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;main&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;./src/worker.ts&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;env&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;VITE_API_URL&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;api&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;as&amp;#x3C;string&gt;&lt;/span&gt;&lt;span&gt;() }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;button title=&quot;Copy to clipboard&quot; data-copied=&quot;Copied!&quot; data-code=&quot;&quot;&gt;() },});&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/button&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;HMR works in dev — edit a route component, the browser
hot-reloads; edit the worker, the Worker reloads.&lt;/li&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;props.env&lt;/code&gt; keeps the beta.39 semantics: &lt;code dir=&quot;auto&quot;&gt;VITE_&lt;/code&gt;-prefixed
keys are inlined into the client/SSR bundle via
&lt;code dir=&quot;auto&quot;&gt;import.meta.env.*&lt;/code&gt;, everything else is a runtime
Worker binding.&lt;/li&gt;
&lt;li&gt;Vite is resolved from the project’s own &lt;code dir=&quot;auto&quot;&gt;node_modules&lt;/code&gt;
first (via &lt;code dir=&quot;auto&quot;&gt;createRequire&lt;/code&gt;) so you control the version.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;aigateway-no-more-update-every-deploy&quot;&gt;AiGateway: no more update-every-deploy&lt;/h2&gt;&lt;a href=&quot;#aigateway-no-more-update-every-deploy&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “AiGateway: no more update-every-deploy”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;Cloudflare.AiGateway&lt;/code&gt; was reporting &lt;code dir=&quot;auto&quot;&gt;update&lt;/code&gt; on every
&lt;code dir=&quot;auto&quot;&gt;bun alchemy deploy&lt;/code&gt;, even when nothing had changed. Two
things were going on:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The provider was diffing against &lt;code dir=&quot;auto&quot;&gt;news&lt;/code&gt; instead of
observed cloud state.&lt;/li&gt;
&lt;li&gt;The provider’s defaults didn’t match what the
Cloudflare API actually returns, so the first
post-create diff always showed drift.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Both are fixed. Defaults now match the API’s response
shape (&lt;code dir=&quot;auto&quot;&gt;0&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;false&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;null&lt;/code&gt; where the API returns those),
and &lt;code dir=&quot;auto&quot;&gt;Diff.ts&lt;/code&gt; gained the helpers needed to compare
observed-vs-desired correctly. Deploys are quiet again
unless something genuinely changed.&lt;/p&gt;
&lt;p&gt;Fixes &lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/issues/332&quot;&gt;#332&lt;/a&gt;
and &lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/issues/334&quot;&gt;#334&lt;/a&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;worker-http-log-full-cause-server-side-return-generic-500&quot;&gt;Worker HTTP: log full Cause server-side, return generic 500&lt;/h2&gt;&lt;a href=&quot;#worker-http-log-full-cause-server-side-return-generic-500&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Worker HTTP: log full Cause server-side, return generic 500”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The Cloudflare Worker HTTP adapter was leaking internal
error detail into 500 responses. The fix flips that: the
full &lt;code dir=&quot;auto&quot;&gt;Cause&lt;/code&gt; (stack, annotations, defects) is logged on
the server, and the client receives a generic
&lt;code dir=&quot;auto&quot;&gt;Internal Server Error&lt;/code&gt; 500. Same behavior as Effect’s
own &lt;code dir=&quot;auto&quot;&gt;HttpServer.serve&lt;/code&gt; defaults — just now consistent
under &lt;code dir=&quot;auto&quot;&gt;Cloudflare.Worker&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This pairs with the beta.39 lifecycle adapter fix and
finishes the cleanup of the Worker HTTP path.&lt;/p&gt;
&lt;p&gt;Fixes &lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/pull/336&quot;&gt;#336&lt;/a&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;sanitize-entrypoint-urls-in-generated-code&quot;&gt;Sanitize entrypoint URLs in generated code&lt;/h2&gt;&lt;a href=&quot;#sanitize-entrypoint-urls-in-generated-code&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Sanitize entrypoint URLs in generated code”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Codegen for Lambda, ECS, EC2-hosted, Cloudflare Worker,
and Cloudflare Container entrypoints was interpolating
&lt;code dir=&quot;auto&quot;&gt;importPath&lt;/code&gt; directly into a template string:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;entrypoint&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;${importPath}&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;entrypoint&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;JSON&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;stringify&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;importPath&lt;/span&gt;&lt;span&gt;)}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;On macOS/Linux this never bit anyone. On Windows, paths
containing backslashes (or any path with embedded quotes,
unicode, etc.) generated invalid TypeScript. &lt;code dir=&quot;auto&quot;&gt;JSON.stringify&lt;/code&gt;
emits a guaranteed-valid JS string literal across every
codegen site.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;other-fixes&quot;&gt;Other fixes&lt;/h2&gt;&lt;a href=&quot;#other-fixes&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Other fixes”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cloudflare.start forwards startup options&lt;/strong&gt; — &lt;code dir=&quot;auto&quot;&gt;start&lt;/code&gt;’s
options were silently dropped before they reached the
container runtime. Thanks
&lt;strong&gt;&lt;a href=&quot;https://github.com/yovanoc&quot;&gt;Christopher Yovanovitch&lt;/a&gt;&lt;/strong&gt;
(&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/pull/341&quot;&gt;#341&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code dir=&quot;auto&quot;&gt;bun alchemy dev&lt;/code&gt; lockfile&lt;/strong&gt; moves to
&lt;code dir=&quot;auto&quot;&gt;@alchemy.run/node-utils&lt;/code&gt; and the legacy &lt;code dir=&quot;auto&quot;&gt;Sidecar/Lock.ts&lt;/code&gt;
is gone (&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/pull/345&quot;&gt;#345&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cloudflare state store version bumped to 5&lt;/strong&gt; — clients
pinned to older versions will refuse to load mismatched
state and prompt you to upgrade.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code dir=&quot;auto&quot;&gt;scopeTransferToStream&lt;/code&gt; reverted&lt;/strong&gt; — the optimization
was causing 415 responses under workerd; reverting
restores the previous (correct) HTTP semantics.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Axiom &lt;code dir=&quot;auto&quot;&gt;smartfilter&lt;/code&gt; chart subtype&lt;/strong&gt; — used by the
internal otel dashboard; available now if you build
your own Axiom charts via &lt;code dir=&quot;auto&quot;&gt;Axiom.Chart&lt;/code&gt;
(&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/pull/339&quot;&gt;#339&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;contributors&quot;&gt;Contributors&lt;/h2&gt;&lt;a href=&quot;#contributors&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Contributors”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Big thank-you to everyone who shipped code in this beta:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/yovanoc&quot;&gt;Christopher Yovanovitch&lt;/a&gt;&lt;/strong&gt; — &lt;code dir=&quot;auto&quot;&gt;Cloudflare.start&lt;/code&gt; options forwarding (&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/pull/341&quot;&gt;#341&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;where-to-go-next&quot;&gt;Where to go next&lt;/h2&gt;&lt;a href=&quot;#where-to-go-next&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Where to go next”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/blob/main/CHANGELOG.md#v200-beta40&quot;&gt;CHANGELOG&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/compare/v2.0.0-beta.39...v2.0.0-beta.40&quot;&gt;Compare v2.0.0-beta.39 → v2.0.0-beta.40&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>alchemy@2.0.0-beta.39</title><link>https://v2.alchemy.run/blog/2026-05-13-beta-39/</link><guid isPermaLink="true">https://v2.alchemy.run/blog/2026-05-13-beta-39/</guid><description>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&apos;s standard HTTP lifecycle (unblocking RpcServer.toHttpEffect), and the SendEmail binding from beta.38 is now wired into Worker binding inference.

</description><pubDate>Wed, 13 May 2026 18:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;v2.0.0-beta.39&lt;/code&gt; is a fix-only release that lands three
things people hit immediately after beta.38: SPAs reading
&lt;code dir=&quot;auto&quot;&gt;import.meta.env.VITE_*&lt;/code&gt;, Effect RPC servers running under
the Cloudflare Worker adapter, and the brand-new
&lt;code dir=&quot;auto&quot;&gt;SendEmail&lt;/code&gt; binding showing up in Worker binding types.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;cloudflarevite-inlines-vite_-env-into-the-bundle&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;Cloudflare.Vite&lt;/code&gt; inlines &lt;code dir=&quot;auto&quot;&gt;VITE_*&lt;/code&gt; env into the bundle&lt;/h2&gt;&lt;a href=&quot;#cloudflarevite-inlines-vite_-env-into-the-bundle&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Cloudflare.Vite inlines VITE_* env into the bundle”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;Cloudflare.Vite(&quot;Site&quot;, { env: { ... } })&lt;/code&gt; was forwarding
&lt;code dir=&quot;auto&quot;&gt;env&lt;/code&gt; only as runtime Worker bindings — the values never
made it into the client (or SSR) bundle. SPAs reading
&lt;code dir=&quot;auto&quot;&gt;import.meta.env.VITE_API_URL&lt;/code&gt; fell back to whatever
default the code hardcoded, breaking dynamic backend URLs
at build time.&lt;/p&gt;
&lt;p&gt;The build step now passes &lt;code dir=&quot;auto&quot;&gt;props.env&lt;/code&gt; through Vite’s
&lt;code dir=&quot;auto&quot;&gt;define&lt;/code&gt; hook, emulating &lt;code dir=&quot;auto&quot;&gt;vite build&lt;/code&gt;’s env semantics:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;web&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Vite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Web&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;env&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;VITE_API_URL&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;worker&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;as&amp;#x3C;string&gt;&lt;/span&gt;&lt;span&gt;() }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// SPA: `import.meta.env.VITE_API_URL` now contains the deployed worker URL.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;button title=&quot;Copy to clipboard&quot; data-copied=&quot;Copied!&quot; data-code=&quot;&quot;&gt;() },});// SPA: &amp;#x60;import.meta.env.VITE_API_URL&amp;#x60; now contains the deployed worker URL.&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/button&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;The rules match Vite itself:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Only &lt;code dir=&quot;auto&quot;&gt;VITE_&lt;/code&gt;-prefixed keys are inlined into the bundle
as &lt;code dir=&quot;auto&quot;&gt;import.meta.env.&amp;#x3C;key&gt;&lt;/code&gt; (matches Vite’s default
&lt;code dir=&quot;auto&quot;&gt;envPrefix&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Non-&lt;code dir=&quot;auto&quot;&gt;VITE_&lt;/code&gt; entries stay out of the bundle but are still
attached to the deployed Worker as runtime bindings.&lt;/li&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;Redacted&lt;/code&gt; values are unwrapped when they’re
&lt;code dir=&quot;auto&quot;&gt;VITE_&lt;/code&gt;-prefixed — opting them into the public bundle
is an explicit choice you make by naming them that way.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The tutorial gains an &lt;a href=&quot;https://v2.alchemy.run/tutorial/cloudflare/vite-spa&quot;&gt;Inject the Worker URL at build
time&lt;/a&gt; section covering the
pattern end-to-end.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;cloudflare-worker-http-adapter--effects-handled-lifecycle&quot;&gt;Cloudflare Worker HTTP adapter — Effect’s handled lifecycle&lt;/h2&gt;&lt;a href=&quot;#cloudflare-worker-http-adapter--effects-handled-lifecycle&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Cloudflare Worker HTTP adapter — Effect’s handled lifecycle”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The Worker HTTP adapter previously hand-rolled the
&lt;code dir=&quot;auto&quot;&gt;HttpServerRequest&lt;/code&gt; / &lt;code dir=&quot;auto&quot;&gt;HttpServerResponse&lt;/code&gt; bridge. That
worked for simple handlers but diverged from Effect’s
&lt;code dir=&quot;auto&quot;&gt;HttpEffect.toHandled&lt;/code&gt; / &lt;code dir=&quot;auto&quot;&gt;toWebHandler&lt;/code&gt; lifecycle in ways
that broke scoped HTTP apps under workerd — most visibly,
&lt;code dir=&quot;auto&quot;&gt;RpcServer.toHttpEffect&lt;/code&gt; hung when served through Alchemy
even though the same app worked under raw Wrangler.&lt;/p&gt;
&lt;p&gt;The adapter now runs handlers through Effect’s standard
HTTP lifecycle while preserving every Worker-specific
behavior:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;cf-connecting-ip&lt;/code&gt; → &lt;code dir=&quot;auto&quot;&gt;remoteAddress&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;the original Cloudflare &lt;code dir=&quot;auto&quot;&gt;Request&lt;/code&gt; service&lt;/li&gt;
&lt;li&gt;patched &lt;code dir=&quot;auto&quot;&gt;request.raw&lt;/code&gt; access&lt;/li&gt;
&lt;li&gt;existing 500 response mapping from &lt;code dir=&quot;auto&quot;&gt;serveWebRequest&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;…plus the parts that were missing: stream-scope transfer,
HEAD body suppression, and request-abort interruption.&lt;/p&gt;
&lt;p&gt;The net effect: anything that worked under
&lt;code dir=&quot;auto&quot;&gt;@effect/platform&lt;/code&gt;’s standard HTTP lifecycle now works
under &lt;code dir=&quot;auto&quot;&gt;Cloudflare.Worker&lt;/code&gt; too. &lt;code dir=&quot;auto&quot;&gt;RpcServer.toHttpEffect&lt;/code&gt;,
in particular, is unblocked.&lt;/p&gt;
&lt;p&gt;— &lt;em&gt;Thanks to &lt;strong&gt;&lt;a href=&quot;https://github.com/wking-io&quot;&gt;Will King&lt;/a&gt;&lt;/strong&gt;
(&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/pull/328&quot;&gt;#328&lt;/a&gt;)
for the fix.&lt;/em&gt; Fixes
&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/issues/327&quot;&gt;#327&lt;/a&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;sendemail-binding-type-inference&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;SendEmail&lt;/code&gt; binding type inference&lt;/h2&gt;&lt;a href=&quot;#sendemail-binding-type-inference&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “SendEmail binding type inference”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;beta.38 added &lt;code dir=&quot;auto&quot;&gt;Cloudflare.SendEmail&lt;/code&gt; but two wiring sites
in &lt;code dir=&quot;auto&quot;&gt;Worker.ts&lt;/code&gt; were missed — the binding type inference
didn’t know about it, and the deploy-time binding
metadata didn’t emit a &lt;code dir=&quot;auto&quot;&gt;send_email&lt;/code&gt; entry. The result:
typing &lt;code dir=&quot;auto&quot;&gt;bindings: { EMAIL: Email }&lt;/code&gt; on a Worker errored,
and deploys silently dropped the binding.&lt;/p&gt;
&lt;p&gt;Both are wired up now — &lt;code dir=&quot;auto&quot;&gt;SendEmail&lt;/code&gt; is a first-class
member of the Worker binding union, the env key carries
the right runtime type, and Cloudflare receives the
expected &lt;code dir=&quot;auto&quot;&gt;send_email&lt;/code&gt; binding metadata at deploy time.&lt;/p&gt;
&lt;p&gt;— &lt;em&gt;Thanks to &lt;strong&gt;&lt;a href=&quot;https://github.com/Gerbuuun&quot;&gt;Gerben Mulder&lt;/a&gt;&lt;/strong&gt;
(&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/pull/326&quot;&gt;#326&lt;/a&gt;)
for catching this.&lt;/em&gt;&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;contributors&quot;&gt;Contributors&lt;/h2&gt;&lt;a href=&quot;#contributors&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Contributors”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Big thank-you to everyone who shipped code in this beta:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/wking-io&quot;&gt;Will King&lt;/a&gt;&lt;/strong&gt; — Cloudflare Worker HTTP effect lifecycle (&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/pull/328&quot;&gt;#328&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/Gerbuuun&quot;&gt;Gerben Mulder&lt;/a&gt;&lt;/strong&gt; — &lt;code dir=&quot;auto&quot;&gt;SendEmail&lt;/code&gt; Worker binding type and meta (&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/pull/326&quot;&gt;#326&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;where-to-go-next&quot;&gt;Where to go next&lt;/h2&gt;&lt;a href=&quot;#where-to-go-next&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Where to go next”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/blob/main/CHANGELOG.md#v200-beta39&quot;&gt;CHANGELOG&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/compare/v2.0.0-beta.38...v2.0.0-beta.39&quot;&gt;Compare v2.0.0-beta.38 → v2.0.0-beta.39&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>alchemy@2.0.0-beta.38</title><link>https://v2.alchemy.run/blog/2026-05-13-beta-38/</link><guid isPermaLink="true">https://v2.alchemy.run/blog/2026-05-13-beta-38/</guid><description>Cloudflare Email Routing and the send_email Worker binding, a new Action plan node for arbitrary Effects that run during apply, a leaner Neon provider on the typed @distilled.cloud/neon SDK, and a transport-error retry fix.

</description><pubDate>Wed, 13 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;v2.0.0-beta.38&lt;/code&gt; adds two new building blocks — full
&lt;strong&gt;Cloudflare Email&lt;/strong&gt; (zone routing + the &lt;code dir=&quot;auto&quot;&gt;send_email&lt;/code&gt;
Worker binding) and the &lt;strong&gt;&lt;code dir=&quot;auto&quot;&gt;Action&lt;/code&gt;&lt;/strong&gt; plan node for
arbitrary Effects that run during apply — plus a
behind-the-scenes Neon refactor onto the typed
&lt;code dir=&quot;auto&quot;&gt;@distilled.cloud/neon&lt;/code&gt; SDK and a fault-tolerance fix in
the apply transport.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;cloudflare-email&quot;&gt;Cloudflare Email&lt;/h2&gt;&lt;a href=&quot;#cloudflare-email&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Cloudflare Email”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Four new resources and one binding cover the whole flow:
turn on Email Routing for a zone, register verified
destination addresses, forward inbound mail with routing
rules, and send outbound mail from a Worker.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// alchemy.run.ts — enable Email Routing on a zone you own&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;routing&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;EmailRouting&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Routing&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;zone&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;example.com&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Register a verified destination&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ops&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;EmailAddress&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Ops&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;email&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;ops@example.com&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Forward inbound info@ → ops@&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rule&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;EmailRule&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;InfoForward&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;zone&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;example.com&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;matchers&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [{ type&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;literal&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; field&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;to&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; value&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;info@example.com&quot;&lt;/span&gt;&lt;span&gt; }]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;actions&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [{ type&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;forward&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; value&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;&quot;ops@example.com&quot;&lt;/span&gt;&lt;span&gt;] }]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Declare a `send_email` binding (the id is the env key)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Email&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;SendEmail&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;EmailOps&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;destinationAddress&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;ops@example.com&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;allowedSenderAddresses&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;&quot;noreply@example.com&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Bind &lt;code dir=&quot;auto&quot;&gt;SendEmail&lt;/code&gt; on a Worker and the runtime client gives
you &lt;code dir=&quot;auto&quot;&gt;send&lt;/code&gt; (parsed) and &lt;code dir=&quot;auto&quot;&gt;sendRaw&lt;/code&gt; (RFC 822 bytes) with the
same Effect error channel as every other binding:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Worker&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Notifier&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{ main&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;meta&lt;/span&gt;&lt;span&gt;.path }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function*&lt;/span&gt;&lt;span&gt; () {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;email&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;SendEmail&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;bind&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Email&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;fetch&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function*&lt;/span&gt;&lt;span&gt; () {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;email&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;send&lt;/span&gt;&lt;span&gt;({&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;noreply@example.com&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;to&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;ops@example.com&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;subject&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;Hello&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;Hi from the edge&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;HttpServerResponse&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;sent&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}).&lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;provide&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;SendEmailBindingLive&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;https://v2.alchemy.run/providers/cloudflare/emailrouting&quot;&gt;Providers › &lt;code dir=&quot;auto&quot;&gt;EmailRouting&lt;/code&gt;&lt;/a&gt; ·
&lt;a href=&quot;https://v2.alchemy.run/providers/cloudflare/emailaddress&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;EmailAddress&lt;/code&gt;&lt;/a&gt; ·
&lt;a href=&quot;https://v2.alchemy.run/providers/cloudflare/emailrule&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;EmailRule&lt;/code&gt;&lt;/a&gt; ·
&lt;a href=&quot;https://v2.alchemy.run/providers/cloudflare/sendemail&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;SendEmail&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;action--effects-that-run-as-part-of-apply&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;Action&lt;/code&gt; — Effects that run as part of apply&lt;/h2&gt;&lt;a href=&quot;#action--effects-that-run-as-part-of-apply&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Action — Effects that run as part of apply”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;An &lt;strong&gt;Action&lt;/strong&gt; is a node in the stack DAG that runs an
arbitrary Effect during apply when its resolved input
changes — the missing primitive for things like database
migrations, cache invalidation, deploy announcements, or
anything else that isn’t a cloud resource but needs to run
in order alongside one.&lt;/p&gt;
&lt;p&gt;The shape is intentionally close to &lt;code dir=&quot;auto&quot;&gt;Resource&lt;/code&gt;: define
once, instantiate in a stack, pass it inputs, get an
&lt;code dir=&quot;auto&quot;&gt;Output&lt;/code&gt; back that downstream nodes can depend on.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Alchemy&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;alchemy&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;effect/Effect&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Sync&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Alchemy&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Action&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Sync&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function*&lt;/span&gt;&lt;span&gt; (input&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;table&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; string }&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; { rows&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;42&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// In a stack:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rows&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Sync&lt;/span&gt;&lt;span&gt;({ table&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;bucket&lt;/span&gt;&lt;span&gt;.name })&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;//          ^? Output&amp;#x3C;{ rows: number }&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;button title=&quot;Copy to clipboard&quot; data-copied=&quot;Copied!&quot; data-code=&quot;&quot;&gt;&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/button&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Unlike a Resource, an Action has no
create/update/replace/delete lifecycle — the engine just
hashes the resolved input and runs the body when it
drifts. Removing the Action from the stack drops its
persisted state in the GC pass; the body is never
re-invoked on delete.&lt;/p&gt;
&lt;p&gt;The plan reports actions on their own row:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Plan: 1 to create | 1 to update | 1 to run&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;~ Api (Cloudflare.Worker)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;+ BucketA (Cloudflare.R2Bucket)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;λ AnnounceDeploy (AnnounceDeploy) [action]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;· DbMigrate (DbMigrate) [action]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;λ&lt;/code&gt; (cyan) means &lt;em&gt;will run this apply&lt;/em&gt;; &lt;code dir=&quot;auto&quot;&gt;·&lt;/code&gt; (gray) means
&lt;em&gt;input hash matches, skip&lt;/em&gt;. &lt;code dir=&quot;auto&quot;&gt;--force&lt;/code&gt; flips skip→run for
actions the same way it does for resources.&lt;/p&gt;
&lt;p&gt;Init-style construction works too, for the common case
where the body needs Effect Services from the stack’s
layers:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Sync&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Alchemy&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Action&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Sync&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function*&lt;/span&gt;&lt;span&gt; () {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;db&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Database&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;logger&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Logger&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function*&lt;/span&gt;&lt;span&gt; (input&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;table&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; string }&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;logger&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;info&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`syncing ${&lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;.table&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; { rows&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;db&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;count&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;.table) }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;The init Effect runs once per process (memoized), so the
runner is shared across every instance and every re-run.&lt;/p&gt;
&lt;p&gt;Actions also participate in the dependency graph in both
directions — they can take resource Outputs as input &lt;em&gt;and&lt;/em&gt;
their own output can be consumed by downstream resources
or other actions. The scheduler waits on a separate
“stable” signal so an action body never observes a
resource’s precreate stub; it only sees terminal cloud
state.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://v2.alchemy.run/concepts/action&quot;&gt;Concepts › Actions&lt;/a&gt;&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;neon-on-distilledcloudneon&quot;&gt;Neon on &lt;code dir=&quot;auto&quot;&gt;@distilled.cloud/neon&lt;/code&gt;&lt;/h2&gt;&lt;a href=&quot;#neon-on-distilledcloudneon&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Neon on @distilled.cloud/neon”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;Neon.Project&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;Neon.Branch&lt;/code&gt; no longer ship a
hand-rolled HTTP wrapper — they route through the typed
&lt;a href=&quot;https://www.npmjs.com/package/@distilled.cloud/neon&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;@distilled.cloud/neon&lt;/code&gt;&lt;/a&gt;
SDK. The user-facing API is unchanged; what’s gone is the
&lt;code dir=&quot;auto&quot;&gt;api.ts&lt;/code&gt; shim, the manual JSON shapes, and the per-call
error mapping.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import * as api from &quot;./api.ts&quot;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import { getProject, updateProject, deleteProject } from &quot;@distilled.cloud/neon/Operations&quot;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;404 handling now uses the SDK’s tagged error directly:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;getProject&lt;/span&gt;&lt;span&gt;({ project_id }).&lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;catchTag&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;NotFound&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; () &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;succeed&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;undefined&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;button title=&quot;Copy to clipboard&quot; data-copied=&quot;Copied!&quot; data-code=&quot;&quot;&gt; Effect.succeed(undefined)),)&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/button&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;This is mostly an internal cleanup, but it pays off
immediately: errors carry typed tags instead of opaque
strings, retries hang off &lt;code dir=&quot;auto&quot;&gt;Schedule&lt;/code&gt; instead of
hand-written &lt;code dir=&quot;auto&quot;&gt;try/catch&lt;/code&gt;, and the next time the upstream
OpenAPI spec moves we regenerate one package instead of
patching one file.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;fault-tolerance-in-the-apply-transport&quot;&gt;Fault tolerance in the apply transport&lt;/h2&gt;&lt;a href=&quot;#fault-tolerance-in-the-apply-transport&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Fault tolerance in the apply transport”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The transport that streams resource lifecycle events
between the apply worker and the renderer now treats
transient send/receive errors as retryable instead of
collapsing the whole run. A flaky connection that drops
mid-apply no longer aborts the stack — the transport
backs off, reconnects, and resumes.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;other-changes-worth-knowing-about&quot;&gt;Other changes worth knowing about&lt;/h2&gt;&lt;a href=&quot;#other-changes-worth-knowing-about&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Other changes worth knowing about”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code dir=&quot;auto&quot;&gt;effect@4.0.0-beta.66&lt;/code&gt;.&lt;/strong&gt; Tracks the latest Effect
release. No public Alchemy API change; downstream apps
pinning Effect themselves should bump in lockstep.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code dir=&quot;auto&quot;&gt;ignore&lt;/code&gt; is now vendored.&lt;/strong&gt; The MIT-licensed
&lt;code dir=&quot;auto&quot;&gt;ignore&lt;/code&gt; package is inlined into the Alchemy build to
shrink the supply-chain surface (one less transitive
dependency for everyone running &lt;code dir=&quot;auto&quot;&gt;alchemy deploy&lt;/code&gt; in CI).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OTLP dashboard refresh.&lt;/strong&gt; Self-hosted OTel dashboards
now have resource-usage ranking and error-rate charts
per Stack / Stage. No code change in user code — it’s
all dashboard config.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;where-to-go-next&quot;&gt;Where to go next&lt;/h2&gt;&lt;a href=&quot;#where-to-go-next&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Where to go next”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/blob/main/CHANGELOG.md#v200-beta38&quot;&gt;CHANGELOG&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/compare/v2.0.0-beta.37...v2.0.0-beta.38&quot;&gt;Compare v2.0.0-beta.37 → v2.0.0-beta.38&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>alchemy@2.0.0-beta.37</title><link>https://v2.alchemy.run/blog/2026-05-12-beta-37/</link><guid isPermaLink="true">https://v2.alchemy.run/blog/2026-05-12-beta-37/</guid><description>Cross-stack and cross-stage references, fully-typed Worker-to-Worker bindings, Workflows with typed I/O, Alchemy.Secret / Alchemy.Variable, cron triggers, an Analytics Engine binding, and R2 buckets that finally empty themselves on destroy.

</description><pubDate>Tue, 12 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;v2.0.0-beta.37&lt;/code&gt; is the biggest beta in a while. The
headline addition is &lt;strong&gt;cross-stack and cross-stage
references&lt;/strong&gt; — the missing piece that lets PR-preview
stages share a database with &lt;code dir=&quot;auto&quot;&gt;staging&lt;/code&gt; instead of
re-provisioning a whole Postgres cluster every time someone
opens a draft PR. On top of that: fully-typed
Worker-to-Worker bindings, typed Workflow I/O, the new
&lt;code dir=&quot;auto&quot;&gt;Alchemy.Secret&lt;/code&gt; / &lt;code dir=&quot;auto&quot;&gt;Alchemy.Variable&lt;/code&gt; one-liners, cron
triggers, and an Analytics Engine binding.&lt;/p&gt;
&lt;p&gt;A bunch of this came from outside the core team — props
to the contributors throughout, and full credits at the
&lt;a href=&quot;#contributors&quot;&gt;bottom of the post&lt;/a&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;cross-stack-and-cross-stage-references&quot;&gt;Cross-stack and cross-stage references&lt;/h2&gt;&lt;a href=&quot;#cross-stack-and-cross-stage-references&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Cross-stack and cross-stage references”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Lazy, typed references to resources deployed by a
&lt;em&gt;different&lt;/em&gt; stack or stage. The use case it was built for:
ephemeral PR-preview stages that need a Neon project,
shouldn’t pay for their own, and should instead share one
that’s owned by &lt;code dir=&quot;auto&quot;&gt;staging&lt;/code&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;pointing-a-pr-stage-at-stagings-database&quot;&gt;Pointing a PR stage at &lt;code dir=&quot;auto&quot;&gt;staging&lt;/code&gt;’s database&lt;/h3&gt;&lt;a href=&quot;#pointing-a-pr-stage-at-stagings-database&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Pointing a PR stage at staging’s database”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Same &lt;code dir=&quot;auto&quot;&gt;alchemy.run.ts&lt;/code&gt;, conditional on the stage. If the
stage looks like a PR preview (&lt;code dir=&quot;auto&quot;&gt;pr-147&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;pr-148&lt;/code&gt;, …),
&lt;code dir=&quot;auto&quot;&gt;Neon.Project.ref&lt;/code&gt; reaches into the &lt;code dir=&quot;auto&quot;&gt;staging&lt;/code&gt; stage’s state
file and pulls out the already-deployed project. Otherwise
the stage creates its own.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;src/Db.ts&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Alchemy&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;alchemy&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Drizzle&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;alchemy/Drizzle&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Neon&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;alchemy/Neon&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;effect/Effect&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;NeonDb&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function*&lt;/span&gt;&lt;span&gt; () {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;stage&lt;/span&gt;&lt;span&gt; } &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Alchemy&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Stack&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;schema&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Drizzle&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Schema&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;app-schema&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;schema&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;./src/schema.ts&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;out&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;./migrations&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// PR previews share the long-lived staging project.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// Every other stage gets its own.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;project&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;stage&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;startsWith&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;pr-&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Neon&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Project&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;ref&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;app-db&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; { stage&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;staging&quot;&lt;/span&gt;&lt;span&gt; })&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Neon&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Project&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;app-db&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; { region&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;aws-us-east-1&quot;&lt;/span&gt;&lt;span&gt; })&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// Branches are cheap and per-stage either way.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;branch&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Neon&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Branch&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;app-branch&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;project&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;migrationsDir&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;schema&lt;/span&gt;&lt;span&gt;.out&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; { project&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; branch&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; schema }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Three things to note:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Same logical id, same type.&lt;/strong&gt; &lt;code dir=&quot;auto&quot;&gt;&quot;app-db&quot;&lt;/code&gt; matches the
id &lt;code dir=&quot;auto&quot;&gt;staging&lt;/code&gt; uses to create the project; &lt;code dir=&quot;auto&quot;&gt;project&lt;/code&gt; is
&lt;code dir=&quot;auto&quot;&gt;Neon.Project&lt;/code&gt; either way, so downstream
(&lt;code dir=&quot;auto&quot;&gt;Neon.Branch({ project })&lt;/code&gt;) doesn’t know or care
whether it’s real or referenced.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Resolved at plan time.&lt;/strong&gt; Alchemy reads the project’s
attributes (id, host, etc.) out of &lt;code dir=&quot;auto&quot;&gt;staging&lt;/code&gt;’s persisted
&lt;a href=&quot;https://v2.alchemy.run/concepts/state-store&quot;&gt;state store&lt;/a&gt;. If &lt;code dir=&quot;auto&quot;&gt;staging&lt;/code&gt;
hasn’t been deployed yet, plan fails loudly with
&lt;code dir=&quot;auto&quot;&gt;InvalidReferenceError&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PR teardown stays scoped.&lt;/strong&gt; &lt;code dir=&quot;auto&quot;&gt;alchemy destroy --stage pr-147&lt;/code&gt; deletes the per-PR &lt;code dir=&quot;auto&quot;&gt;Neon.Branch&lt;/code&gt; but doesn’t
touch the shared project — this stage doesn’t own it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Deploy &lt;code dir=&quot;auto&quot;&gt;staging&lt;/code&gt; once, then PR stages can point at it:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;Terminal window&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;alchemy&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;deploy&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--stage&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;staging&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;# creates the project once&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;alchemy&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;deploy&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--stage&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pr-147&lt;/span&gt;&lt;span&gt;         &lt;/span&gt;&lt;span&gt;# references it, creates only the branch&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;The full file lives in
&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/tree/main/examples/cloudflare-neon-drizzle/src/Db.ts&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;examples/cloudflare-neon-drizzle/src/Db.ts&lt;/code&gt;&lt;/a&gt;;
the guide is at
&lt;a href=&quot;https://v2.alchemy.run/guides/shared-database&quot;&gt;Guides › Shared database across stages&lt;/a&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;referencing-an-entire-stacks-outputs&quot;&gt;Referencing an entire stack’s outputs&lt;/h3&gt;&lt;a href=&quot;#referencing-an-entire-stacks-outputs&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Referencing an entire stack’s outputs”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The example above pulls one &lt;strong&gt;resource&lt;/strong&gt; across stages.
The other shape — pulling a &lt;strong&gt;whole stack’s outputs&lt;/strong&gt; —
is what you reach for in a monorepo where the frontend
package wants to read the backend stack’s deployed URL.&lt;/p&gt;
&lt;p&gt;Declare a typed stack handle once:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;backend/src/Stack.ts&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Alchemy&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;alchemy&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Backend&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;extends&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Alchemy&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Stack&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;Backend&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{ &lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; string }&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;span&gt;()(&lt;/span&gt;&lt;span&gt;&quot;Backend&quot;&lt;/span&gt;&lt;span&gt;) {}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;button title=&quot;Copy to clipboard&quot; data-copied=&quot;Copied!&quot; data-code=&quot;&quot;&gt;()(&amp;#x22;Backend&amp;#x22;) {}&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/button&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Deploy the backend with &lt;code dir=&quot;auto&quot;&gt;Backend.make(...)&lt;/code&gt; (the typed
shorthand for &lt;code dir=&quot;auto&quot;&gt;Alchemy.Stack&lt;/code&gt;), then &lt;code dir=&quot;auto&quot;&gt;yield* Backend&lt;/code&gt; from
the frontend’s stack to get its outputs back, type-checked:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;frontend/alchemy.run.ts&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Alchemy&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;alchemy&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;alchemy/Cloudflare&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;Backend&lt;/span&gt;&lt;span&gt; } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;backend&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;effect/Effect&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Alchemy&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Stack&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;Frontend&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{ providers&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;providers&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; state&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;state&lt;/span&gt;&lt;span&gt;() }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function*&lt;/span&gt;&lt;span&gt; () {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// Resolves Backend&apos;s outputs from the same stage of the same&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// stack name. `pr-42` frontend reads `pr-42` backend.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;backend&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Backend&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;//    ^? { url: string }&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Vite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Website&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;env&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;VITE_API_URL&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;backend&lt;/span&gt;&lt;span&gt;.url }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;yield* Backend&lt;/code&gt; defaults to “same stage as the consumer”.
When you need to pin — say, the prod frontend always reads
the prod backend regardless of which branch deploys it —
use &lt;code dir=&quot;auto&quot;&gt;Backend.stage.&amp;#x3C;name&gt;&lt;/code&gt;:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;backend&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Backend&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;stage&lt;/span&gt;&lt;span&gt;.prod&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// always pin to prod&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;backend&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Backend&lt;/span&gt;&lt;span&gt;.stage[&lt;/span&gt;&lt;span&gt;&quot;pr-42&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// arbitrary stage name&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Under the hood, both shapes are
&lt;a href=&quot;https://v2.alchemy.run/concepts/outputs#ref&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;Output.stackRef&lt;/code&gt;&lt;/a&gt; /
&lt;a href=&quot;https://v2.alchemy.run/concepts/resource#ref&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;Resource.ref&lt;/code&gt;&lt;/a&gt; reading the
state store. The new APIs just make them ergonomic.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://v2.alchemy.run/concepts/references&quot;&gt;Concepts › References&lt;/a&gt; ·
&lt;a href=&quot;https://v2.alchemy.run/guides/shared-database&quot;&gt;Guides › Shared database&lt;/a&gt; ·
&lt;a href=&quot;https://v2.alchemy.run/guides/monorepo&quot;&gt;Guides › Monorepos&lt;/a&gt; ·
&lt;a href=&quot;https://v2.alchemy.run/tutorial/cloudflare/branch-from-shared-database&quot;&gt;Tutorial › Branch from a shared database&lt;/a&gt;&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;alchemysecret-and-alchemyvariable&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;Alchemy.Secret&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;Alchemy.Variable&lt;/code&gt;&lt;/h2&gt;&lt;a href=&quot;#alchemysecret-and-alchemyvariable&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Alchemy.Secret and Alchemy.Variable”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The boring part of a stack — wiring an env var into a
deploy target — used to leak across three files. One yield
now collapses it into a line that’s also a typed runtime
accessor.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// alchemy.run.ts — declare once on the Worker&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Worker&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Api&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{ main&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;meta&lt;/span&gt;&lt;span&gt;.path }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function*&lt;/span&gt;&lt;span&gt; () {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;apiKey&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Alchemy&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Secret&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;OPENAI_API_KEY&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;//    ^? Output&amp;#x3C;Redacted&amp;#x3C;string&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;fetch&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function*&lt;/span&gt;&lt;span&gt; () {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// …and read the bound value inside the handler.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;apiKey&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;// Redacted&amp;#x3C;string&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;HttpServerResponse&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;`key has ${&lt;/span&gt;&lt;span&gt;Redacted&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;length&lt;/span&gt;&lt;span&gt;} chars`&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;button title=&quot;Copy to clipboard&quot; data-copied=&quot;Copied!&quot; data-code=&quot;&quot;&gt;&gt;    return {      fetch: Effect.gen(function* () {        // …and read the bound value inside the handler.        const key = yield* apiKey; // Redacted&lt;string&gt;        return HttpServerResponse.text(          &amp;#x60;key has ${Redacted.value(key).length} chars&amp;#x60;,        );      }),    };  }),);&quot;&gt;&lt;div&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;Alchemy.Variable&lt;/code&gt; is the same shape without &lt;code dir=&quot;auto&quot;&gt;Redacted&lt;/code&gt;:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;port&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Alchemy&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Variable&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;PORT&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;3000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;flags&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Alchemy&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Variable&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;FLAGS&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; { beta&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt; })&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// inside fetch&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;p&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; port&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;   &lt;/span&gt;&lt;span&gt;// number — 3000&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; flags&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;// { beta: true }&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Both accept a literal, an &lt;code dir=&quot;auto&quot;&gt;Effect&lt;/code&gt;, a &lt;code dir=&quot;auto&quot;&gt;Config&lt;/code&gt;, or default
to reading the value from the active &lt;code dir=&quot;auto&quot;&gt;ConfigProvider&lt;/code&gt; under
the same name. The same call routes to the platform’s
native secret/variable binding — Cloudflare &lt;code dir=&quot;auto&quot;&gt;secret_text&lt;/code&gt;
for &lt;code dir=&quot;auto&quot;&gt;Secret&lt;/code&gt;, Lambda encrypted env vars on AWS — and the
runtime accessor decodes back to the original type.&lt;/p&gt;
&lt;p&gt;The deeper write-up is at
&lt;a href=&quot;https://v2.alchemy.run/blog/2026-05-11-secrets-and-variables&quot;&gt;Secrets and Variables&lt;/a&gt;;
docs at
&lt;a href=&quot;https://v2.alchemy.run/concepts/secrets&quot;&gt;Concepts › Secrets&lt;/a&gt; ·
&lt;a href=&quot;https://v2.alchemy.run/guides/secrets&quot;&gt;Guides › Secrets and env vars&lt;/a&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;worker-to-worker-bindings-fully-typed&quot;&gt;Worker-to-Worker bindings, fully typed&lt;/h2&gt;&lt;a href=&quot;#worker-to-worker-bindings-fully-typed&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Worker-to-Worker bindings, fully typed”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;A Worker is now bindable as a binding on another Worker,
and the caller gets full RPC types on the other side — no
codegen, no manual interfaces, no &lt;code dir=&quot;auto&quot;&gt;as&lt;/code&gt; casts on &lt;code dir=&quot;auto&quot;&gt;env&lt;/code&gt;.
Three call shapes are supported, all on the same
deployment.&lt;/p&gt;
&lt;p&gt;The example: a &lt;code dir=&quot;auto&quot;&gt;Backend&lt;/code&gt; Worker exposing both an RPC method
and an HTTP route, plus a TanStack Start frontend calling
it three different ways. (This is the
&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/tree/main/examples/cloudflare-tanstack&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;examples/cloudflare-tanstack&lt;/code&gt;&lt;/a&gt;
project — cut down to the relevant pieces.)&lt;/p&gt;
&lt;p&gt;The backend Worker:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;src/backend.ts&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;alchemy/Cloudflare&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;effect/Effect&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;HttpServerRequest&lt;/span&gt;&lt;span&gt; } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;effect/unstable/http/HttpServerRequest&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;HttpServerResponse&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;effect/unstable/http/HttpServerResponse&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Bucket&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;R2Bucket&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Bucket&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Backend&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;extends&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Worker&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;Backend&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;span&gt;()(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;Backend&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{ main&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;meta&lt;/span&gt;&lt;span&gt;.path }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function*&lt;/span&gt;&lt;span&gt; () {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;bucket&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;R2Bucket&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;bind&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Bucket&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;// RPC method — callable via `backend.hello(key)` on the other side.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;hello&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fn&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Backend.hello&quot;&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;function*&lt;/span&gt;&lt;span&gt; (key&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;object&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;bucket&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;object&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;object&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;// HTTP handler — callable via `env.BACKEND.fetch(...)`.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;fetch&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function*&lt;/span&gt;&lt;span&gt; () {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;request&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;HttpServerRequest&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;URL&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;request&lt;/span&gt;&lt;span&gt;.url&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;http://backend&quot;&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;searchParams&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;key&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;HttpServerResponse&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;missing key&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; { status&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;400&lt;/span&gt;&lt;span&gt; })&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;request&lt;/span&gt;&lt;span&gt;.method &lt;/span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;GET&quot;&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;object&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;bucket&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;object&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;null&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;HttpServerResponse&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;not found&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; { status&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;404&lt;/span&gt;&lt;span&gt; })&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;HttpServerResponse&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;stream&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;object&lt;/span&gt;&lt;span&gt;.body)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;HttpServerResponse&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;method not allowed&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; { status&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;405&lt;/span&gt;&lt;span&gt; })&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}).&lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;provide&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;R2BucketBindingLive&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;) {}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;button title=&quot;Copy to clipboard&quot; data-copied=&quot;Copied!&quot; data-code=&quot;&quot;&gt;()(  &amp;#x22;Backend&amp;#x22;,  { main: import.meta.path },  Effect.gen(function* () {    const bucket = yield* Cloudflare.R2Bucket.bind(Bucket);    return {      // RPC method — callable via &amp;#x60;backend.hello(key)&amp;#x60; on the other side.      hello: Effect.fn(&amp;#x22;Backend.hello&amp;#x22;)(function* (key: string) {        const object = yield* bucket.get(key);        return object === null ? null : yield* object.text();      }),      // HTTP handler — callable via &amp;#x60;env.BACKEND.fetch(...)&amp;#x60;.      fetch: Effect.gen(function* () {        const request = yield* HttpServerRequest;        const key = new URL(request.url, &amp;#x22;http://backend&amp;#x22;).searchParams.get(&amp;#x22;key&amp;#x22;);        if (!key) return HttpServerResponse.text(&amp;#x22;missing key&amp;#x22;, { status: 400 });        if (request.method === &amp;#x22;GET&amp;#x22;) {          const object = yield* bucket.get(key);          return object === null            ? HttpServerResponse.text(&amp;#x22;not found&amp;#x22;, { status: 404 })            : HttpServerResponse.stream(object.body);        }        return HttpServerResponse.text(&amp;#x22;method not allowed&amp;#x22;, { status: 405 });      }),    };  }).pipe(Effect.provide(Cloudflare.R2BucketBindingLive)),) {}&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/button&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Wire it into another Worker as a binding:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;alchemy.run.ts&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Backend&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;Bucket&lt;/span&gt;&lt;span&gt; } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;./src/backend.ts&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Website&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Vite&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Website&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;bindings&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;BUCKET&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Bucket&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;       &lt;/span&gt;&lt;span&gt;// R2 binding&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;BACKEND&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Backend&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;     &lt;/span&gt;&lt;span&gt;// Worker-to-Worker binding&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Now the caller has three ways to talk to the backend. All
three are real, all three are typed, all three work in the
same handler — pick whichever fits the call site.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// frontend route handler&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;alchemy/Cloudflare&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Backend&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;../backend.ts&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;env&lt;/span&gt;&lt;span&gt; } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;../env.ts&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Option 1 — async binding (just call the platform API directly).&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;object&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;env&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;BUCKET&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt;(key)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Option 2 — Worker-to-Worker fetch over the service binding.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;res&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;env&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;BACKEND&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fetch&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`https://backend/?key=${&lt;/span&gt;&lt;span&gt;encodeURIComponent&lt;/span&gt;&lt;span&gt;(key)&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Option 3 — typed RPC. `toPromiseApi&amp;#x3C;Backend&gt;` wraps the wire-shape&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// binding into a Promise&amp;#x3C;T&gt; view that throws on `Effect.fail` and&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// unwraps stream envelopes — full method signatures from `Backend`.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;backend&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;toPromiseApi&amp;#x3C;&lt;/span&gt;&lt;span&gt;Backend&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;env&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;BACKEND&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;backend&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;hello&lt;/span&gt;&lt;span&gt;(key)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;//    ^? string | null  (typed end-to-end)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;button title=&quot;Copy to clipboard&quot; data-copied=&quot;Copied!&quot; data-code=&quot;&quot;&gt;&amp;#x60; wraps the wire-shape// binding into a Promise&lt;/button&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;&lt;/string&gt;&lt;/button&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;</content:encoded></item><item><title>Secrets and Variables</title><link>https://v2.alchemy.run/blog/2026-05-11-secrets-and-variables/</link><guid isPermaLink="true">https://v2.alchemy.run/blog/2026-05-11-secrets-and-variables/</guid><description>Bind a value into your deploy target&apos;s env and get back a typed runtime accessor — the same one-liner works for Cloudflare Workers and AWS Lambda.

</description><pubDate>Mon, 11 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Wiring an env var into a deploy target is supposed to be the
boring part of a stack — but in practice it usually leaks across
two or three files: a value pulled out of &lt;code dir=&quot;auto&quot;&gt;.env&lt;/code&gt;, a binding
declared on the resource, and an unsafe &lt;code dir=&quot;auto&quot;&gt;env.MY_KEY!&lt;/code&gt; somewhere in
your handler.&lt;/p&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;Alchemy.Secret&lt;/code&gt; and &lt;code dir=&quot;auto&quot;&gt;Alchemy.Variable&lt;/code&gt; collapse all of that into
a single line that’s also a typed runtime accessor.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;apiKey&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Alchemy&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Secret&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;OPENAI_API_KEY&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;//    ^? Output&amp;#x3C;Redacted&amp;#x3C;string&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;button title=&quot;Copy to clipboard&quot; data-copied=&quot;Copied!&quot; data-code=&quot;&quot;&gt;&gt;&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/button&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;That one yield does three things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;reads the value from the active
&lt;a href=&quot;https://effect.website/docs/configuration&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;ConfigProvider&lt;/code&gt;&lt;/a&gt;
at deploy time (no &lt;code dir=&quot;auto&quot;&gt;process.env.X!&lt;/code&gt; needed)&lt;/li&gt;
&lt;li&gt;attaches it to the active deploy target’s environment as the
platform’s secret binding (Cloudflare → &lt;code dir=&quot;auto&quot;&gt;secret_text&lt;/code&gt;,
Lambda → encrypted env var)&lt;/li&gt;
&lt;li&gt;hands you back an accessor — &lt;code dir=&quot;auto&quot;&gt;yield* apiKey&lt;/code&gt; inside &lt;code dir=&quot;auto&quot;&gt;fetch&lt;/code&gt;
resolves the value at runtime, typed as &lt;code dir=&quot;auto&quot;&gt;Redacted&amp;#x3C;string&gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;one-api-every-runtime&quot;&gt;One API, every runtime&lt;/h2&gt;&lt;a href=&quot;#one-api-every-runtime&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “One API, every runtime”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;The same call works whether the active runtime is a Cloudflare
Worker, an AWS Lambda, or anything else that implements Alchemy’s
serverless contract. Each provider routes the value to its native
secret/variable binding under the hood:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// Cloudflare Worker&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Worker&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Worker&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; { main&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;meta&lt;/span&gt;&lt;span&gt;.path }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function*&lt;/span&gt;&lt;span&gt; () {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;apiKey&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Alchemy&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Secret&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;OPENAI_API_KEY&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;fetch&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function*&lt;/span&gt;&lt;span&gt; () {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;apiKey&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;// Redacted&amp;#x3C;string&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;HttpServerResponse&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`got ${&lt;/span&gt;&lt;span&gt;Redacted&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;length&lt;/span&gt;&lt;span&gt;} chars`&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// AWS Lambda — exact same shape&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;AWS&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Lambda&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Function&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Function&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; { main&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;meta&lt;/span&gt;&lt;span&gt;.filename&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; url&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function*&lt;/span&gt;&lt;span&gt; () {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;apiKey&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Alchemy&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Secret&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;OPENAI_API_KEY&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;fetch&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function*&lt;/span&gt;&lt;span&gt; () {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;apiKey&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;HttpServerResponse&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`got ${&lt;/span&gt;&lt;span&gt;Redacted&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;length&lt;/span&gt;&lt;span&gt;} chars`&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;button title=&quot;Copy to clipboard&quot; data-copied=&quot;Copied!&quot; data-code=&quot;&quot;&gt;        return HttpServerResponse.text(&amp;#x60;got ${Redacted.value(key).length} chars&amp;#x60;);      }),    };  }),);// AWS Lambda — exact same shapeexport default AWS.Lambda.Function(&amp;#x22;Function&amp;#x22;, { main: import.meta.filename, url: true },  Effect.gen(function* () {    const apiKey = yield* Alchemy.Secret(&amp;#x22;OPENAI_API_KEY&amp;#x22;);    return {      fetch: Effect.gen(function* () {        const key = yield* apiKey;        return HttpServerResponse.text(&amp;#x60;got ${Redacted.value(key).length} chars&amp;#x60;);      }),    };  }),);&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/button&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h2 id=&quot;plain-values-when-you-dont-need-redaction&quot;&gt;Plain values when you don’t need redaction&lt;/h2&gt;&lt;a href=&quot;#plain-values-when-you-dont-need-redaction&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Plain values when you don’t need redaction”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;Alchemy.Variable&lt;/code&gt; is the same shape without the &lt;code dir=&quot;auto&quot;&gt;Redacted&lt;/code&gt;
wrapper. Strings deploy as &lt;code dir=&quot;auto&quot;&gt;plain_text&lt;/code&gt;, anything else as JSON,
and the runtime accessor returns the original type:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;port&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Alchemy&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Variable&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;PORT&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;3000&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;flags&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Alchemy&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Variable&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;FLAGS&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; { beta&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt; })&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// later, in fetch:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;p&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; port&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;// number — 3000&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; flags&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;// { beta: true }&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;No JSON parsing, no &lt;code dir=&quot;auto&quot;&gt;as&lt;/code&gt; casts — the type you put in is the type
you get back.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;four-input-shapes&quot;&gt;Four input shapes&lt;/h2&gt;&lt;a href=&quot;#four-input-shapes&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Four input shapes”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Both helpers accept a literal, an &lt;code dir=&quot;auto&quot;&gt;Effect&lt;/code&gt;, a &lt;code dir=&quot;auto&quot;&gt;Config&lt;/code&gt;, or default
to reading from &lt;code dir=&quot;auto&quot;&gt;Config&lt;/code&gt; under the same name:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Alchemy&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Secret&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;API_KEY&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;                              &lt;/span&gt;&lt;span&gt;// Config.redacted(&quot;API_KEY&quot;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Alchemy&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Secret&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;API_KEY&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;sk-123&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;                    &lt;/span&gt;&lt;span&gt;// string literal&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Alchemy&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Secret&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;API_KEY&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;succeed&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;sk-123&quot;&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// Effect&amp;#x3C;string | Redacted&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;Alchemy&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Secret&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;API_KEY&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Config&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;OPENAI_KEY&quot;&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;// Config&amp;#x3C;string | Redacted&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;button title=&quot;Copy to clipboard&quot; data-copied=&quot;Copied!&quot; data-code=&quot;&quot;&gt;Alchemy.Secret(&amp;#x22;API_KEY&amp;#x22;, Config.string(&amp;#x22;OPENAI_KEY&amp;#x22;)); // Config&lt;string Redacted=&quot;&quot;&gt;&quot;&gt;&lt;div&gt;&lt;/div&gt;
&lt;p&gt;The last two are where this earns its keep: pull a token from a
vault inside an &lt;code dir=&quot;auto&quot;&gt;Effect&lt;/code&gt;, or rename it on the way through with
&lt;code dir=&quot;auto&quot;&gt;Config.string(&quot;OTHER_NAME&quot;)&lt;/code&gt; — the binding on the deploy target
is still &lt;code dir=&quot;auto&quot;&gt;API_KEY&lt;/code&gt;, the source just changed.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;where-to-go-next&quot;&gt;Where to go next&lt;/h2&gt;&lt;a href=&quot;#where-to-go-next&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Where to go next”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://v2.alchemy.run/concepts/secrets&quot;&gt;Concepts › Secrets and Variables&lt;/a&gt; — how the
bind/use phases work and how to choose between &lt;code dir=&quot;auto&quot;&gt;Alchemy.Secret&lt;/code&gt;,
&lt;code dir=&quot;auto&quot;&gt;Alchemy.Variable&lt;/code&gt;, and the platform’s own secret-store
resources.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://v2.alchemy.run/guides/secrets&quot;&gt;Guides › Secrets and env vars&lt;/a&gt; — the full
step-by-step for taking &lt;code dir=&quot;auto&quot;&gt;OPENAI_API_KEY&lt;/code&gt; from &lt;code dir=&quot;auto&quot;&gt;.env&lt;/code&gt; to a
&lt;code dir=&quot;auto&quot;&gt;secret_text&lt;/code&gt; binding on a Worker.&lt;/li&gt;
&lt;/ul&gt;&lt;/string&gt;&lt;/button&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;</content:encoded></item><item><title>alchemy@2.0.0-beta.36</title><link>https://v2.alchemy.run/blog/2026-05-09-beta-36/</link><guid isPermaLink="true">https://v2.alchemy.run/blog/2026-05-09-beta-36/</guid><description>Cloudflare Images binding, Hyperdrive as a Worker binding, R2 object lifecycle rules, and a dev-mode networking fix.

</description><pubDate>Sat, 09 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;v2.0.0-beta.36&lt;/code&gt; is mostly a Cloudflare-themed release —
three new Worker bindings (Images, Hyperdrive,
R2 lifecycle policies), all from outside the core team.
Props to the contributors throughout, and full credits in
the &lt;a href=&quot;#contributors&quot;&gt;Contributors section&lt;/a&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;cloudflare-images-binding&quot;&gt;Cloudflare Images binding&lt;/h2&gt;&lt;a href=&quot;#cloudflare-images-binding&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Cloudflare Images binding”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Cloudflare’s image transformation runtime, exposed as a
Worker binding. The Effect-native client takes an Effect
&lt;code dir=&quot;auto&quot;&gt;Stream&amp;#x3C;Uint8Array&gt;&lt;/code&gt; input — typically the request body —
and either streams a transformed image back out or returns
typed metadata.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// alchemy.run.ts — declare the pipeline resource&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Pipeline&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Images&lt;/span&gt;&lt;span&gt;({ name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;PIPELINE&quot;&lt;/span&gt;&lt;span&gt; })&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;// in your Worker&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ImageWorker&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;extends&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Worker&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;ImageWorker&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;span&gt;()(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;ImageWorker&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{ main&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;meta&lt;/span&gt;&lt;span&gt;.filename }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function*&lt;/span&gt;&lt;span&gt; () {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;images&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Images&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;bind&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Pipeline&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;fetch&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function*&lt;/span&gt;&lt;span&gt; () {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;request&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;HttpServerRequest&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// Probe the upload — returns format, width, height, etc.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;request&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;url&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;endsWith&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/info&quot;&lt;/span&gt;&lt;span&gt;)) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;info&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;images&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;info&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;request&lt;/span&gt;&lt;span&gt;.stream)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;HttpServerResponse&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;info&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;// Transform: resize to 512×512 WebP, stream the result back.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;transformed&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;images&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;input&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;request&lt;/span&gt;&lt;span&gt;.stream)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;transform&lt;/span&gt;&lt;span&gt;({ width&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;512&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; height&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;512&lt;/span&gt;&lt;span&gt; })&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;output&lt;/span&gt;&lt;span&gt;({ format&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;image/webp&quot;&lt;/span&gt;&lt;span&gt; })&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;HttpServerResponse&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;stream&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;transformed&lt;/span&gt;&lt;span&gt;.body)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}).&lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;provide&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;ImagesBindingLive&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;) {}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;button title=&quot;Copy to clipboard&quot; data-copied=&quot;Copied!&quot; data-code=&quot;&quot;&gt;()(  &amp;#x22;ImageWorker&amp;#x22;,  { main: import.meta.filename },  Effect.gen(function* () {    const images = yield* Cloudflare.Images.bind(Pipeline);    return {      fetch: Effect.gen(function* () {        const request = yield* HttpServerRequest;        // Probe the upload — returns format, width, height, etc.        if (request.url.endsWith(&amp;#x22;/info&amp;#x22;)) {          const info = yield* images.info(request.stream);          return yield* HttpServerResponse.json(info);        }        // Transform: resize to 512×512 WebP, stream the result back.        const transformed = yield* images          .input(request.stream)          .transform({ width: 512, height: 512 })          .output({ format: &amp;#x22;image/webp&amp;#x22; });        return HttpServerResponse.stream(transformed.body);      }),    };  }).pipe(Effect.provide(Cloudflare.ImagesBindingLive)),) {}&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/button&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;— &lt;em&gt;Thanks to &lt;strong&gt;Alex&lt;/strong&gt; (&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/pull/237&quot;&gt;#237&lt;/a&gt;)
for the contribution.&lt;/em&gt;
&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/blob/main/packages/alchemy/src/Cloudflare/Images/Images.ts&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;Images.ts&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;hyperdrive-in-worker-bindings&quot;&gt;Hyperdrive in Worker bindings&lt;/h2&gt;&lt;a href=&quot;#hyperdrive-in-worker-bindings&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Hyperdrive in Worker bindings”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;Hyperdrive&lt;/code&gt; resources are bindable on Workers the same way
as R2, KV, D1. Two flavors to know:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Declare a Hyperdrive over an existing origin string.&lt;/strong&gt;
Useful when the database lives outside of Alchemy (existing
RDS, Supabase, etc.):&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Hyperdrive&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Hyperdrive&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;DbPool&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;origin&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { connectionString&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;process&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;env&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;POSTGRES_URL&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Wire it onto a Neon branch you already deployed.&lt;/strong&gt;
&lt;code dir=&quot;auto&quot;&gt;Neon.Branch&lt;/code&gt; exposes a pre-parsed &lt;code dir=&quot;auto&quot;&gt;origin&lt;/code&gt; output that
&lt;code dir=&quot;auto&quot;&gt;Cloudflare.Hyperdrive&lt;/code&gt; takes directly — Alchemy orders the
deploy graph correctly:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;src/Db.ts&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;NeonDb&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function*&lt;/span&gt;&lt;span&gt; () {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;project&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Neon&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Project&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;app-db&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; { region&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;aws-us-east-1&quot;&lt;/span&gt;&lt;span&gt; })&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;branch&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Neon&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Branch&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;app-branch&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; { project })&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; { project&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; branch }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Hyperdrive&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function*&lt;/span&gt;&lt;span&gt; () {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;branch&lt;/span&gt;&lt;span&gt; } &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;NeonDb&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Hyperdrive&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;app-hyperdrive&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;origin&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;branch&lt;/span&gt;&lt;span&gt;.origin&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;// direct (non-pooled) Neon endpoint&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Bind it on the Worker and read the pooled connection
string at runtime — Hyperdrive does the connection pooling
so the Worker can spin up a fresh &lt;code dir=&quot;auto&quot;&gt;pg&lt;/code&gt; client per request
without exhausting the database:&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Api&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;extends&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Worker&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;Api&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;span&gt;()(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;Api&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;main&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;meta&lt;/span&gt;&lt;span&gt;.path&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;compatibility&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { flags&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;&quot;nodejs_compat&quot;&lt;/span&gt;&lt;span&gt;] }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function*&lt;/span&gt;&lt;span&gt; () {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;hd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Hyperdrive&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;bind&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Hyperdrive&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;fetch&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function*&lt;/span&gt;&lt;span&gt; () {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;connectionString&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;hd&lt;/span&gt;&lt;span&gt;.connectionString&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rows&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;promise&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; () &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;client&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;new&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Client&lt;/span&gt;&lt;span&gt;({ &lt;/span&gt;&lt;span&gt;connectionString&lt;/span&gt;&lt;span&gt; })&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;client&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;connect&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;try&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;r&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;client&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;query&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;SELECT now() as now&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;r&lt;/span&gt;&lt;span&gt;.rows&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;finally&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;await&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;client&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;end&lt;/span&gt;&lt;span&gt;().&lt;/span&gt;&lt;span&gt;catch&lt;/span&gt;&lt;span&gt;(() &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;span&gt; {})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;HttpServerResponse&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt;({ &lt;/span&gt;&lt;span&gt;rows&lt;/span&gt;&lt;span&gt; })&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}).&lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;provide&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;HyperdriveConnectionLive&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;) {}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;button title=&quot;Copy to clipboard&quot; data-copied=&quot;Copied!&quot; data-code=&quot;&quot;&gt;()(  &amp;#x22;Api&amp;#x22;,  {    main: import.meta.path,    compatibility: { flags: [&amp;#x22;nodejs_compat&amp;#x22;] },  },  Effect.gen(function* () {    const hd = yield* Cloudflare.Hyperdrive.bind(Hyperdrive);    return {      fetch: Effect.gen(function* () {        const connectionString = yield* hd.connectionString;        const rows = yield* Effect.promise(async () =&gt; {          const client = new Client({ connectionString });          await client.connect();          try {            const r = await client.query(&amp;#x22;SELECT now() as now&amp;#x22;);            return r.rows;          } finally {            await client.end().catch(() =&gt; {});          }        });        return yield* HttpServerResponse.json({ rows });      }),    };  }).pipe(Effect.provide(Cloudflare.HyperdriveConnectionLive)),) {}&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/button&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;— &lt;em&gt;Thanks to &lt;strong&gt;Baptiste Arnaud&lt;/strong&gt;
(&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/pull/282&quot;&gt;#282&lt;/a&gt;)
for the contribution.&lt;/em&gt;
&lt;a href=&quot;https://v2.alchemy.run/tutorial/cloudflare/neon-hyperdrive&quot;&gt;Tutorial › Neon + Hyperdrive&lt;/a&gt;&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;r2-lifecycle-rules&quot;&gt;R2 lifecycle rules&lt;/h2&gt;&lt;a href=&quot;#r2-lifecycle-rules&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “R2 lifecycle rules”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Object lifecycle policies on &lt;code dir=&quot;auto&quot;&gt;R2Bucket&lt;/code&gt; — age-based
deletion, storage-class transitions, multipart-upload
abort — declared inline alongside the rest of the bucket
config. Max 1000 rules per bucket; pass an empty array (or
omit) to clear all rules.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Logs&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;R2Bucket&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Logs&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;lifecycleRules&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;archive-then-delete&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;prefix&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;logs/&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;// After 60 days: move to Infrequent Access.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;storageClassTransitions&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;condition&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { type&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;Age&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; maxAge&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;60&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;60&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;24&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;60&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;storageClass&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;InfrequentAccess&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;// After 365 days: delete entirely.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;deleteObjectsTransition&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;condition&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { type&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;Age&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; maxAge&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;60&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;60&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;24&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;365&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;// Stale multipart uploads — drop after 7 days.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;abortMultipartUploadsTransition&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;condition&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { type&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;Age&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; maxAge&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;60&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;60&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;24&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;7&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Each entry is reconciled in place — edit the array and the
next deploy applies the delta against R2’s live policy.&lt;/p&gt;
&lt;p&gt;— &lt;em&gt;Thanks to &lt;strong&gt;Baptiste Arnaud&lt;/strong&gt;
(&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/pull/284&quot;&gt;#284&lt;/a&gt;)
for the contribution.&lt;/em&gt; See &lt;a href=&quot;https://developers.cloudflare.com/r2/buckets/object-lifecycles/&quot;&gt;Cloudflare R2 docs › Object
lifecycles&lt;/a&gt;
for the underlying behavior.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;fixes-worth-knowing-about&quot;&gt;Fixes worth knowing about&lt;/h2&gt;&lt;a href=&quot;#fixes-worth-knowing-about&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Fixes worth knowing about”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code dir=&quot;auto&quot;&gt;*.localhost&lt;/code&gt; resolution in dev mode.&lt;/strong&gt; &lt;code dir=&quot;auto&quot;&gt;bun alchemy dev&lt;/code&gt; now routes &lt;code dir=&quot;auto&quot;&gt;*.localhost&lt;/code&gt; hostnames through a
custom undici dispatcher, so cross-Worker &lt;code dir=&quot;auto&quot;&gt;fetch&lt;/code&gt; calls
to e.g. &lt;code dir=&quot;auto&quot;&gt;https://backend.localhost&lt;/code&gt; resolve to the local
sidecar instead of failing DNS.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;performance&quot;&gt;Performance&lt;/h2&gt;&lt;a href=&quot;#performance&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Performance”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Smoke tests install canaries at the workspace root&lt;/strong&gt;
rather than per-fixture. Batched smoke runs are
noticeably faster on cold caches.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;contributors&quot;&gt;Contributors&lt;/h2&gt;&lt;a href=&quot;#contributors&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Contributors”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Big thank-you to everyone who shipped code in this beta:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Alex&lt;/strong&gt; — Cloudflare Images binding (&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/pull/237&quot;&gt;#237&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Baptiste Arnaud&lt;/strong&gt; — Hyperdrive in Worker bindings (&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/pull/282&quot;&gt;#282&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Baptiste Arnaud&lt;/strong&gt; — R2 lifecycle rules (&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/pull/284&quot;&gt;#284&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;where-to-go-next&quot;&gt;Where to go next&lt;/h2&gt;&lt;a href=&quot;#where-to-go-next&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Where to go next”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/blob/main/CHANGELOG.md#v200-beta36&quot;&gt;CHANGELOG&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/alchemy-run/alchemy-effect/compare/v2.0.0-beta.35...v2.0.0-beta.36&quot;&gt;Compare v2.0.0-beta.35 → v2.0.0-beta.36&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>alchemy@2.0.0-beta.35</title><link>https://v2.alchemy.run/blog/2026-05-08-beta-35/</link><guid isPermaLink="true">https://v2.alchemy.run/blog/2026-05-08-beta-35/</guid><description>A Stream-shaped Effect consumer for Cloudflare Queues, R2 bucket custom domains, non-string env bindings on Workers, Neon logical replication, and a round of CLI quality-of-life.

</description><pubDate>Fri, 08 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;v2.0.0-beta.35&lt;/code&gt; is out. The headline addition is an
Effect-native, &lt;code dir=&quot;auto&quot;&gt;Stream&lt;/code&gt;-shaped consumer API for Cloudflare
Queues — write a queue handler the same way you’d write
any other Effect pipeline. Plus R2 bucket custom domains,
non-string Worker env bindings, Neon logical replication,
and a handful of CLI polish. Community contributors get
inline shoutouts; full credits in the
&lt;a href=&quot;#contributors&quot;&gt;Contributors section&lt;/a&gt;.&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;cloudflaremessagesqueuesubscribe--effect-native-queue-consumer&quot;&gt;&lt;code dir=&quot;auto&quot;&gt;Cloudflare.messages(queue).subscribe(...)&lt;/code&gt; — Effect-native queue consumer&lt;/h2&gt;&lt;a href=&quot;#cloudflaremessagesqueuesubscribe--effect-native-queue-consumer&quot;&gt;&lt;span aria-hidden=&quot;true&quot;&gt;&lt;svg width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;currentcolor&quot; d=&quot;m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span&gt;Section titled “Cloudflare.messages(queue).subscribe(...) — Effect-native queue consumer”&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;Process Cloudflare Queue batches as a typed Effect &lt;code dir=&quot;auto&quot;&gt;Stream&lt;/code&gt;,
with &lt;code dir=&quot;auto&quot;&gt;ack&lt;/code&gt;/&lt;code dir=&quot;auto&quot;&gt;retry&lt;/code&gt; exposed per message. The handler returns
when the batch is done; failed messages get retried up to
&lt;code dir=&quot;auto&quot;&gt;maxRetries&lt;/code&gt;. Same Worker, same Effect runtime, same
bindings — the queue consumer is just another &lt;code dir=&quot;auto&quot;&gt;yield*&lt;/code&gt; in
the init phase.&lt;/p&gt;
&lt;p&gt;A real producer-and-consumer pair: a Worker accepts POSTs
to &lt;code dir=&quot;auto&quot;&gt;/queue/send&lt;/code&gt;, the consumer writes each message to R2
as JSON so the result is observable. Bindings already on
the Worker (&lt;code dir=&quot;auto&quot;&gt;bucket&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;queue&lt;/code&gt;) are in scope inside the
stream handler — the consumer is a peer to the Worker’s
init phase, not a separate file.&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;alchemy/Cloudflare&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;effect/Effect&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;as&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Stream&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;effect/Stream&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;Bucket&lt;/span&gt;&lt;span&gt; } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;./Bucket.ts&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; { &lt;/span&gt;&lt;span&gt;Queue&lt;/span&gt;&lt;span&gt; } &lt;/span&gt;&lt;span&gt;from&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;./Queue.ts&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;QueueMessageBody&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;sentAt&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; number&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;export&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Api&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;extends&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Worker&lt;/span&gt;&lt;span&gt;&amp;#x3C;&lt;/span&gt;&lt;span&gt;Api&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;span&gt;()(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&quot;Api&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{ main&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;meta&lt;/span&gt;&lt;span&gt;.filename }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function*&lt;/span&gt;&lt;span&gt; () {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;bucket&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;R2Bucket&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;bind&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Bucket&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;queueResource&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Queue&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;queue&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;QueueBinding&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;bind&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;queueResource&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// Consumer side. Each batch arrives as a Stream of QueueMessage&amp;#x3C;Body&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// success ack()s every message, failure retry()s. Crash mid-batch and&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;// unprocessed messages are redelivered.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;messages&amp;#x3C;&lt;/span&gt;&lt;span&gt;QueueMessageBody&lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;queueResource&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;batchSize&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;25&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;maxRetries&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}).&lt;/span&gt;&lt;span&gt;subscribe&lt;/span&gt;&lt;span&gt;((stream) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;Stream&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;runForEach&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;stream&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; (msg) &lt;/span&gt;&lt;span&gt;=&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;bucket&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;put&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`/queue/${&lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;body&lt;/span&gt;&lt;span&gt;.id&lt;/span&gt;&lt;span&gt;}`&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;JSON&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;stringify&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;.body)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;httpMetadata&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; { contentType&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;application/json&quot;&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.asVoid)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;// Producer side: POST /queue/send adds a message.&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;fetch&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;gen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;function*&lt;/span&gt;&lt;span&gt; () {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;request&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;HttpServerRequest&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;request&lt;/span&gt;&lt;span&gt;.url &lt;/span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;/queue/send&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;request&lt;/span&gt;&lt;span&gt;.method &lt;/span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;POST&quot;&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;request&lt;/span&gt;&lt;span&gt;.text&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;QueueMessageBody&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;id&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;crypto&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;randomUUID&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;sentAt&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Date&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;now&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;queue&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;send&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yield*&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;HttpServerResponse&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt;({ sent&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;msg&lt;/span&gt;&lt;span&gt; }&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; { status&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;202&lt;/span&gt;&lt;span&gt; })&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;HttpServerResponse&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;ok&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;})&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}).&lt;/span&gt;&lt;span&gt;pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;Effect&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;provide&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;Layer&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;mergeAll&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;R2BucketBindingLive&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;QueueBindingLive&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;Cloudflare&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;QueueEventSourceLive&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;// required for `messages(...)` to dispatch&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;) {}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;button title=&quot;Copy to clipboard&quot; data-copied=&quot;Copied!&quot; data-code=&quot;&quot;&gt;()(  &amp;#x22;Api&amp;#x22;,  { main: import.meta.filename },  Effect.gen(function* () {    const bucket = yield* Cloudflare.R2Bucket.bind(Bucket);    const queueResource = yield* Queue;    const queue = yield* Cloudflare.QueueBinding.bind(queueResource);    // Consumer side. Each batch arrives as a Stream of QueueMessage&lt;/button&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;</content:encoded></item></channel></rss>