Overview
Every binding kind Sproutboat exposes on env, and how binding calls reach the broker.
Bindings follow the Cloudflare Workers binding APIs, implemented by Sproutboat on your own server, so a handler is written as a Worker is: export default { async fetch(request, env, ctx) { ... } } satisfies ExportedHandler<Env>, with env as the second argument and every binding call awaited. Each page lists the methods that are supported, and where Sproutboat adds one (D1 backup(), R2 transfer URLs, Analytics Engine query()) it says so, because that code does not run on Workers.
export default {
async fetch(request, env, ctx) {
await env.DB.prepare("INSERT INTO hits (path) VALUES (?)").bind(new URL(request.url).pathname).run();
const hits = Number((await env.COUNTS.get("hits")) ?? 0) + 1;
await env.COUNTS.put("hits", String(hits));
return Response.json({ hits });
},
} satisfies ExportedHandler<Env>;
Env is written for you by sproutboat types, from sproutboat.jsonc.
Whether a binding call returns its value directly or a Promise depends on the compatibility date. From 2026-10-24 D1 calls (prepare().raw(), .run(), .all(), .first(), batch() and exec()) return Promises, as on Workers, from 2026-10-25 KV calls do, and from 2026-10-26 R2 calls do. Before those dates they are synchronous and return their value directly. await works at every date, so write await env.DB.prepare(...).run() and your code is correct on both sides, and runs unchanged on Cloudflare. A call you do not await that fails is reported as an unhandled rejection (a log line and an unhandledrejection event); it does not stop the process. The handler page lists every date.
On the platform, binding calls go over loopback to the broker running next to your sprout; a standalone binary has the bindings compiled in. See The handler.
Available bindings
| Binding | Accessed as | Config key |
|---|---|---|
| KV | env.NAME |
kv_namespaces |
| D1-compatible SQLite | env.NAME |
d1_databases |
| R2-compatible object storage | env.NAME |
r2_buckets |
| Queues | env.NAME |
queues |
| Secrets | env.NAME |
secrets |
| Cron | scheduled(controller, env, ctx) |
triggers.crons |
| Service bindings | env.NAME |
services |
| Static assets | env.ASSETS |
assets |
| Durable Objects | env.NAME |
durable_objects |
| Rate limiting | env.NAME |
ratelimiters |
| Outbound fetch | fetch() |
none |
| Vars | env.NAME |
vars |
| Analytics Engine | env.NAME |
analytics_engine_datasets |
| Version metadata | env.NAME |
version_metadata |
Every binding is declared in sproutboat.jsonc. KV namespaces, D1 databases, R2 buckets and queues are account-level resources that deploy can create for you; see Storage resources.