Bindings Reference
Cloudwerk provides seamless access to all Cloudflare bindings. In route handlers, you can import bindings directly for a clean, ergonomic API.
Importable Bindings (Recommended)
Section titled “Importable Bindings (Recommended)”The simplest way to access bindings in route handlers is to import them directly:
// app/api/posts/route.tsimport { DB, CACHE } from '@cloudwerk/core/bindings'import { json } from '@cloudwerk/core'
export async function GET() { const { results: posts } = await DB.prepare('SELECT * FROM posts').all() return json(posts)}Run the type generator to enable TypeScript autocomplete for your bindings:
cloudwerk bindings generate-typesThis creates .cloudwerk/types/ with type definitions for your bindings and updates your tsconfig.json to include them.
Available Exports
Section titled “Available Exports”The @cloudwerk/core/bindings module provides:
| Export | Description |
|---|---|
Named exports (e.g., DB, KV, BUCKET) | Direct access to bindings by name |
bindings | Proxy object for dynamic access to any binding |
getBinding<T>(name) | Type-safe binding retrieval |
hasBinding(name) | Check if a binding exists |
getBindingNames() | List all available binding names |
queues | Typed queue producers (see below) |
services | Typed service RPC proxy (see below) |
durableObjects | Typed Durable Object namespaces (see below) |
import { bindings, getBinding, hasBinding, getBindingNames } from '@cloudwerk/core/bindings'
export async function GET() { // Dynamic access const db = bindings.DB as D1Database
// Type-safe retrieval const kv = getBinding<KVNamespace>('CACHE')
// Conditional access if (hasBinding('ANALYTICS')) { const analytics = getBinding<AnalyticsEngine>('ANALYTICS') // Use analytics... }
// List all bindings const available = getBindingNames() return json({ availableBindings: available })}Accessing Bindings in Loaders
Section titled “Accessing Bindings in Loaders”In loader functions, access bindings via the context parameter:
export async function loader({ context }: LoaderArgs) { // Access bindings via context const db = context.db; // D1 Database const kv = context.kv; // KV Namespace const r2 = context.r2; // R2 Bucket const env = context.env; // Environment variables}Typed Queue Producers
Section titled “Typed Queue Producers”Cloudwerk provides a typed queues proxy for sending messages to queue consumers defined in app/queues/.
import { queues } from '@cloudwerk/core/bindings'
// Send to email queue (defined in app/queues/email.ts)await queues.email.send({ subject: 'Welcome!', body: 'Thanks for signing up.',})
// Send with delayawait queues.email.send(delayedMessage, { delaySeconds: 60 })
// Batch sendawait queues.notifications.sendBatch([ { userId: '1', type: 'email', message: 'Hello' }, { userId: '2', type: 'push', message: 'Hello' },])Queue Utilities
Section titled “Queue Utilities”import { queues, getQueue, hasQueue, getQueueNames } from '@cloudwerk/core/bindings'
// Type-safe queue retrievalinterface EmailMessage { to: string subject: string body: string}const emailQueue = getQueue<EmailMessage>('email')
// Check if queue existsif (hasQueue('analytics')) { await queues.analytics.send({ event: 'pageview' })}
// List all queuesconst available = getQueueNames() // ['email', 'notifications', 'analytics']Queue Interface
Section titled “Queue Interface”interface Queue<T = unknown> { send(message: T, options?: SendOptions): Promise<void> sendBatch(messages: T[], options?: SendOptions): Promise<void>}
interface SendOptions { delaySeconds?: number // 0-43200 (max 12 hours) contentType?: 'json' | 'text' | 'bytes' | 'v8'}Typed Services Proxy
Section titled “Typed Services Proxy”Cloudwerk provides a typed services proxy for calling service methods defined in app/services/.
import { services } from '@cloudwerk/core/bindings'
// Call email service (defined in app/services/email/service.ts)const result = await services.email.send({ subject: 'Hello', body: '<h1>Welcome!</h1>',})
// Call payment serviceconst checkout = await services.payments.createCheckout({ customerId: 'cus_123', items: [{ priceId: 'price_123', quantity: 1 }], successUrl: '/success', cancelUrl: '/cancel',})Service Utilities
Section titled “Service Utilities”import { services, getService, hasService, getServiceNames } from '@cloudwerk/core/bindings'
// Type-safe service retrievalinterface EmailService { send(params: { to: string; subject: string; body: string }): Promise<{ success: boolean }>}const email = getService<EmailService>('email')
// Check if service existsif (hasService('analytics')) { await services.analytics.track({ event: 'signup' })}
// List all servicesconst available = getServiceNames() // ['email', 'payments', 'cache']Transparent Routing
Section titled “Transparent Routing”The services proxy automatically routes calls based on the configured mode:
// Your code (identical for both modes)await services.email.send({ to: '...' })
// Local mode: Direct function call (no latency)// Extracted mode: RPC via Cloudflare service bindingTyped Durable Objects Proxy
Section titled “Typed Durable Objects Proxy”Cloudwerk provides a typed durableObjects proxy for accessing Durable Objects defined in app/objects/.
import { durableObjects } from '@cloudwerk/core/bindings'
// Get a counter DO by nameconst counter = durableObjects.counter.get('user-123')
// Call RPC methods directlyconst count = await counter.increment(5)const current = await counter.getCount()await counter.reset()
// Get by unique IDconst uniqueId = durableObjects.counter.newUniqueId()const newCounter = durableObjects.counter.getById(uniqueId)Durable Object Utilities
Section titled “Durable Object Utilities”import { durableObjects, getDurableObject, hasDurableObject } from '@cloudwerk/core/bindings'
// Type-safe DO retrievalinterface CounterDO { increment(amount?: number): Promise<number> getCount(): Promise<number>}const counterNs = getDurableObject<CounterDO>('counter')
// Check if DO existsif (hasDurableObject('game')) { const game = durableObjects.game.get('room-abc')}Namespace Interface
Section titled “Namespace Interface”interface DurableObjectNamespaceProxy<T> { get(name: string): T // Get by name (deterministic) getById(id: DurableObjectId): T // Get by unique ID newUniqueId(): DurableObjectId // Generate unique ID idFromName(name: string): DurableObjectId idFromString(hexId: string): DurableObjectId}D1 Database
Section titled “D1 Database”Cloudflare D1 is a serverless SQLite database.
Configuration
Section titled “Configuration”# wrangler.toml[[d1_databases]]binding = "DB"database_name = "my-database"database_id = "your-database-id"// Query builder (recommended)const users = await context.db .selectFrom('users') .where('status', '=', 'active') .execute();
// Raw queriesconst result = await context.env.DB .prepare('SELECT * FROM users WHERE id = ?') .bind(userId) .first();
// Batch queriesconst results = await context.env.DB.batch([ context.env.DB.prepare('SELECT * FROM users'), context.env.DB.prepare('SELECT * FROM posts'),]);interface D1Database { prepare(query: string): D1PreparedStatement; batch<T>(statements: D1PreparedStatement[]): Promise<D1Result<T>[]>; run(query: string): Promise<D1ExecResult>;}
interface D1PreparedStatement { bind(...values: unknown[]): D1PreparedStatement; first<T>(column?: string): Promise<T | null>; all<T>(): Promise<D1Result<T>>; run(): Promise<D1ExecResult>;}KV Namespace
Section titled “KV Namespace”Cloudflare Workers KV provides key-value storage.
Configuration
Section titled “Configuration”# wrangler.toml[[kv_namespaces]]binding = "KV"id = "your-kv-id"// Get valueconst value = await context.kv.get('key');const jsonValue = await context.kv.get('key', 'json');const streamValue = await context.kv.get('key', 'stream');
// Set valueawait context.kv.put('key', 'value');await context.kv.put('key', JSON.stringify(data));
// With expirationawait context.kv.put('key', 'value', { expirationTtl: 3600, // 1 hour in seconds});
// With metadataawait context.kv.put('key', 'value', { metadata: { createdAt: Date.now() },});
// Deleteawait context.kv.delete('key');
// List keysconst keys = await context.kv.list();const prefixedKeys = await context.kv.list({ prefix: 'user:' });interface KVNamespace { get(key: string, type?: 'text'): Promise<string | null>; get(key: string, type: 'json'): Promise<unknown | null>; get(key: string, type: 'arrayBuffer'): Promise<ArrayBuffer | null>; get(key: string, type: 'stream'): Promise<ReadableStream | null>;
put(key: string, value: string | ArrayBuffer | ReadableStream, options?: KVPutOptions): Promise<void>;
delete(key: string): Promise<void>;
list(options?: KVListOptions): Promise<KVListResult>;}R2 Object Storage
Section titled “R2 Object Storage”Cloudflare R2 provides S3-compatible object storage.
Configuration
Section titled “Configuration”# wrangler.toml[[r2_buckets]]binding = "R2"bucket_name = "my-bucket"// Get objectconst object = await context.r2.get('path/to/file.txt');if (object) { const text = await object.text(); const arrayBuffer = await object.arrayBuffer(); const blob = await object.blob();}
// Put objectawait context.r2.put('path/to/file.txt', 'Hello, World!');await context.r2.put('path/to/file.txt', fileStream, { httpMetadata: { contentType: 'text/plain', },});
// Delete objectawait context.r2.delete('path/to/file.txt');
// List objectsconst objects = await context.r2.list();const prefixedObjects = await context.r2.list({ prefix: 'uploads/', limit: 100,});
// Head (metadata only)const head = await context.r2.head('path/to/file.txt');interface R2Bucket { get(key: string): Promise<R2ObjectBody | null>; put(key: string, value: ReadableStream | ArrayBuffer | string, options?: R2PutOptions): Promise<R2Object>; delete(key: string): Promise<void>; list(options?: R2ListOptions): Promise<R2Objects>; head(key: string): Promise<R2Object | null>;}Environment Variables
Section titled “Environment Variables”Access environment variables and secrets.
Configuration
Section titled “Configuration”# wrangler.toml[vars]ENVIRONMENT = "production"API_URL = "https://api.example.com"Set secrets:
wrangler secret put API_KEY// Access variablesconst environment = context.env.ENVIRONMENT;const apiUrl = context.env.API_URL;const apiKey = context.env.API_KEY; // SecretVectorize
Section titled “Vectorize”Vector database for AI applications.
Configuration
Section titled “Configuration”# wrangler.toml[[vectorize]]binding = "VECTORIZE"index_name = "my-index"// Insert vectorsawait context.env.VECTORIZE.insert([ { id: 'doc-1', values: [0.1, 0.2, 0.3], metadata: { title: 'Doc 1' } },]);
// Query vectorsconst results = await context.env.VECTORIZE.query(queryVector, { topK: 10, filter: { category: 'tech' },});Cloudflare Workers AI for inference.
Configuration
Section titled “Configuration”# wrangler.toml[ai]binding = "AI"// Text generationconst response = await context.env.AI.run('@cf/meta/llama-2-7b-chat-int8', { prompt: 'Hello!',});
// Embeddingsconst embeddings = await context.env.AI.run('@cf/baai/bge-base-en-v1.5', { text: 'Hello, world!',});
// Image classificationconst result = await context.env.AI.run('@cf/microsoft/resnet-50', { image: imageArrayBuffer,});Next Steps
Section titled “Next Steps”- Queues API - Queue consumer reference
- Services API - Service extraction reference
- Durable Objects API - Durable Object reference
- Database Guide - D1 in depth
- Authentication - Using KV for sessions