Workers for Platforms
The backend path is Cloudflare Workers-backed from the start.
You are not inventing a separate backend setup from scratch. Vibecodr already gives the server-side part of the project a Workers-powered home.
Backend guide
If you like Cloudflare Workers but do not want to spend your energy rebuilding the same backend setup every time, this is the shape Vibecodr gives you: env.pulse config, policy fetch, setup capabilities, structured logs, sanitized request access, and managed file workflows wrapped around a publishable product.
Workers for Platforms
You are not inventing a separate backend setup from scratch. Vibecodr already gives the server-side part of the project a Workers-powered home.
Public config
Public defaults stay explicit while credentials and platform wiring stay out of public source.
Policy fetch
The public docs teach policy fetch rather than arbitrary unconstrained fetch or internal dispatch details.
R2 stays platform-managed
That keeps bundle, asset, and capsule storage aligned with the product's publishing and access model.
What this feels like
The important question is not whether Workers are involved. It is how that infrastructure turns into something practical for API routes, automations, integrations, and durable state without draining the fun out of building.
Write the fun part
The useful Cloudflare pieces show up where you need them, while the account-separation and storage plumbing stay out of your way.
Same-origin API routes
That keeps the public app and the backend routes under one project shape instead of splitting the mental model across multiple deployment surfaces, and BUMP IT keeps future releases on that same app identity.
App-focused bindings
env.pulse, env.fetch, env.secrets, env.connections, env.log, env.request, and env.state are the practical beginner surface. R2 remains managed through product workflows.
Access map
Use those documented capabilities for runtime work, use env.runtime.capabilities() when you need a safe picture of what the Pulse can access, treat env.db as advanced compatibility SQL, and let Vibecodr keep hold of file workflows, deployment setup, and account separation.
How you use it
Put backend code in src/server/ or server/. Supported files publish as same-origin /api/* routes, so the public project keeps one surface while the Worker-backed backend lives behind it.
Route model
That keeps the client-side experience and backend endpoints under one project instead of making you explain a second deployment surface to everyone who touches the app.
Managed infrastructure
Reach for documented capabilities like env.pulse, policy fetch, credentials, structured logs, and sanitized request access in Pulse code, then let Vibecodr handle asset storage, publish wiring, and the shared-platform safety work around them.
What you can reach
Use this section to see what can live directly in Pulse code today, what needs a Pro upgrade, and what still stays managed instead of turning into another thing you have to wire yourself.
Public .pulse config
env.pulseRead non-secret user-configurable defaults without teaching flat public config like env.MODEL.
Usage: Put public values in .pulse and read them as env.pulse.NAME inside server-side Pulses.
const units = env.pulse.DEFAULT_UNITS || "metric";
const queue = env.pulse.SUPPORT_QUEUE_NAME || "support";
return { units, queue };
Dispatch proxy + encrypted secret storage
env.secretsCall external APIs without turning your Pulse code into a plain secret viewer.
Usage: Use env.fetch with env.secrets.bearer/header/query so secret values stay policy-bound.
if (!env.secrets.has("PROVIDER_API_KEY")) {
return { error: "Configure PROVIDER_API_KEY first" };
}
const response = await env.fetch("https://api.example.com/v1/messages", {
method: "POST",
auth: env.secrets.bearer("PROVIDER_API_KEY"),
});
return await response.json();
Provider-scoped account capability via dispatch
env.connectionsUse connected provider accounts without manually storing provider access tokens inside user code.
Usage: Use setup-reviewed connected accounts for provider calls.
const github = env.connections.use("github");
const me = await github.fetch("/user", {
headers: { "User-Agent": "vibecodr-pulse" },
});
return await me.json();
Policy outbound fetch
env.fetchPerform outbound HTTP requests through the server-side trust boundary instead of from the client-side vibe.
Usage: Use env.fetch for public outbound calls that should follow platform egress policy.
const res = await env.fetch("https://api.weather.com/v1/forecast?city=SF");
if (!res.ok) {
return { error: "Upstream error: " + res.status };
}
return await res.json();
Pulse State operation coordination
env.stateCoordinate backend work across Pulse calls on the Workers-backed runtime with stable operation keys.
Usage: Use descriptor-declared state resources with runOnce(), claim(), keyFromRequest(), and guarded effects when repeated calls need to agree on the same protected operation; retentionTtlSeconds controls duplicate-memory retention and is capped by plan. Vibecodr persists the coordination record in platform-owned durable storage, so cold starts do not erase it and idle retention mostly costs tiny stored metadata.
const key = await env.state.httpMutations.keyFromRequest(env.request);
return env.state.httpMutations.runOnce(key, async () => {
await chargeCustomer();
return { accepted: true };
});
Structured logs + sanitized request access
env.log + env.requestWrite request-scoped logs and inspect sanitized request metadata without platform credential headers.
Usage: Use env.log directly for structured runtime logging. env.waitUntil is only best-effort after-response work, not durable processing.
const requestUrl = new URL(env.request.url);
env.log.info("pulse.request", { path: requestUrl.pathname });
return { received: true, path: requestUrl.pathname };
Descriptor-backed runtime capability snapshot
env.runtime.capabilities()Inspect the Pulse's creator-facing capability surface without probing raw env bindings or platform internals.
Usage: Use it when the Pulse needs to confirm which public config keys, secret names, provider connections, raw-body routes, state resources, or advanced SQL compatibility were exposed to this deployment.
const caps = env.runtime.capabilities();
return {
publicConfig: caps.pulse.publicConfigKeys,
providers: caps.connections.declaredProviders,
stateResources: caps.state.activeResources,
};
Access map
This is the clearest honest map of the current Cloudflare story on Vibecodr, without pretending every feature is already exposed the same way.
| Capability | How you access it | Availability | Truth status |
|---|---|---|---|
| .pulse config | env.pulse.* |
All Pulse plans | Public, non-secret user config only. |
| Advanced SQL compatibility | env.db |
Explicit advanced path | Not the beginner backend model and not auto-migrated to Pulse State. |
| R2 | Studio and API file workflows |
Platform-managed | No direct env.r2 binding in PulseEnv today. |
| Secrets and connections | env.secrets and env.connections via env.fetch |
Plan-aware | Credential access is server-mediated rather than direct raw token access. |
| Pulse State coordination | env.state.<name>.runOnce()/claim()/keyFromRequest() |
All Pulse plans with plan-shaped monthly caps | Tracks operation lifecycle across Pulse calls: new, pending, completed, failed, conflicting, replay-aware, and quota-admitted. Use a data surface or connected service for app records. |
| Runtime capability reflection | env.runtime.capabilities() |
All Pulse plans | Safe creator-facing reflection only: declared keys and availability, never secret values or raw platform binding internals. |
Connections today
The connection story is intentionally narrow for now. That is more honest than pretending every provider is already surfaced equally inside the runtime.
OAuth-backed provider
Where Vibecodr steps in
The important boundary is straightforward: use documented Pulse capabilities for backend logic, treat advanced SQL compatibility separately, and let Vibecodr keep file storage, deployment wiring, and project separation under platform control.
No direct env.r2 today
That distinction matters because bundle and asset storage are tied to publishing, Studio, and API pathways rather than arbitrary Worker-side file access.
No platform handles
That keeps implementation plumbing out of beginner examples and public source.
Pro gates are explicit
That keeps the Worker story honest: compatibility SQL exists separately from beginner documentation and future Pulse State work.
Keep exploring
Start with backend capability, client-side runtime, or the broader publish-and-share loop, depending on which part still feels fuzzy.
Bottom line
The result is a cleaner backend workflow: direct access where you need it, less setup noise where you do not, and a much clearer picture of how Pulse capabilities and platform-managed storage fit into a real project.
FAQ
No. Beginner Pulses should start with input, env.pulse public config, env.fetch policy outbound fetch, env.log structured logs, env.request sanitized request access, env.state coordination, secrets, and connections.
No. env.db is advanced compatibility SQL, not the starter model, and no automatic Pulse State migration is promised by that compatibility surface.
Not currently. R2 is platform-managed for capsule files, bundles, and assets through Studio and API workflows instead of being exposed as a direct Pulse binding.
No. Raw binding names, route catalogs, grants, logs, state, and ops metadata stay owner/platform projections rather than public projection metadata.
Use env.runtime.capabilities(). It reflects a safe creator-facing view of declared config keys, secrets, connections, raw-body routes, and Pulse State resources without exposing secret values or platform binding internals.
You get a Workers-backed backend path that already feels shaped for apps: env.pulse config, policy fetch, setup capabilities, structured logs, sanitized requests, and managed file storage, without having to rebuild the same app plumbing from scratch.