Skip to content
Bindings / Configuration

Bindings

Binding configuration

Which Wrangler bindings run on OpenOrange as is, which need a service that you supply, and which are not supported.

OpenOrange reads bindings from the same Wrangler configuration as wrangler dev. Each binding is one of three kinds:

  • Runs as is: OpenOrange implements the Cloudflare API. You set nothing.
  • Needs a service: OpenOrange implements the Cloudflare API on a service that you supply, such as your SMTP server. You set one variable that points to it.
  • Not supported: the binding loads, but Orange has no backend for it. The Worker loads, and env.NAME exists. Each method call throws an error that names the binding and suggests an alternative. Analytics Engine is the exception: writeDataPoint() accepts data points and drops them, as wrangler dev does.

orange doctor reports each binding of your project as one of these kinds. It does not list variables (vars, .dev.vars, and .env), because they need nothing on Rivet.

Where a binding stores data depends on the command. Under orange dev, Rivet Actors run on a local Rivet Engine, and data stays on your machine. Under orange deploy, they run on your Rivet cluster. A service binding sends data to the service that you set.

Matrix

BindingWrangler keyKindRuns onNotes
VariablesvarsRuns as isThe Worker processStrings and JSON values.
Local secrets.dev.vars, .envRuns as isThe Worker processLoaded like wrangler dev. See Variables and secrets.
Secrets Storesecrets_store_secretsRuns as isThe Worker processLocal values come from .dev.vars or the process environment. See Secrets Store.
Version metadataversion_metadataRuns as isThe Worker processSee Version metadata.
unsafe_evalunsafe.bindingsRuns as isThe Worker process
Static assetsassetsRuns as isLocal filesSee Static assets.
Durable Objectsdurable_objectsRuns as isOne Rivet Actor for each objectPartial. Same-Worker classes from new_sqlite_classes and new_classes migrations. See Durable Objects.
Durable Objects from another Workerdurable_objects with script_nameRuns as isThe other Worker’s Rivet ActorsBoth Workers run in one orange dev. See Multiple Workers.
Service bindings to this WorkerservicesRuns as isThe Worker processfetch(), JS RPC, named entrypoints, props, and ctx.exports.
Service bindings to another WorkerservicesRuns as isThe other Worker’s processPartial. Run both Workers in one orange dev with repeated -c. connect() and WebSocket upgrades throw. See Multiple Workers.
Dispatch namespacesdispatch_namespacesRuns as isThe Workers of the orange dev sessionPartial. See Multiple Workers.
KVkv_namespacesRuns as isOne Rivet Actor for each namespaceSee KV.
D1d1_databasesRuns as isOne Rivet Actor for each databaseSee D1.
Rate Limitingratelimits, unsafe.bindingsRuns as isOne Rivet Actor for each namespaceSee Rate Limiting.
R2r2_bucketsRuns as isOne Rivet Actor for each bucket, or your S3-compatible storeSet ORANGE_R2_<BUCKET>_S3_* to use Amazon S3, Cloudflare R2, Google Cloud Storage, or Backblaze B2. See R2.
Queuesqueues.producers, queues.consumersRuns as isOne Rivet Actor for each queueSee Queues.
WorkflowsworkflowsRuns as isCloudflare’s own Workflows engine, with one Rivet Actor for each instancePartial. See Workflows.
Tail Workerstail_consumersRuns as isRivet Durable StreamsPartial. See Tail Workers.
Worker Loaderworker_loadersRuns as isOne Node.js process for each dynamic Worker, in an agentOS VMPartial. See Worker Loader.
Workers AIaiNeeds a serviceAn OpenAI-compatible providerSet OPENROUTER_API_KEY, or ORANGE_AI_BASE_URL for OpenAI, Groq, Together AI, or Fireworks AI. See Workers AI.
Send Emailsend_emailNeeds a serviceYour SMTP serverSet ORANGE_EMAIL_SMTP_URL to Amazon SES, Resend, Postmark, SendGrid, or Mailgun. Without it, the binding throws. See Email.
Browser RenderingbrowserNeeds a serviceA hosted browser or your Chrome, through its DevTools Protocol endpointSet ORANGE_BROWSER_CDP_URL to Browserbase, Browserless, or Steel. Without it, the binding throws. See Browser Rendering.
HyperdrivehyperdriveNeeds a serviceYour database, with a direct connectionSet the local connection string, as for wrangler dev, such as PlanetScale, Amazon RDS, Neon, or Supabase. No pooling or query cache. See Hyperdrive.
Analytics Engineanalytics_engine_datasetsNot supportedNothingwriteDataPoint() accepts data points and drops them, as wrangler dev does.
VectorizevectorizeNot supportedNothingSee Other bindings.
Images, Media, Streamimages, media, streamNot supportedNothingSee Other bindings.
PipelinespipelinesNot supportedNothing
AI Searchai_searchNot supportedNothing
mTLS certificatesmtls_certificatesNot supportedNothing
VPCvpc_networks, vpc_servicesNot supportedNothingUse fetch() to reach the host network directly.
Legacy blobstext_blobs, data_blobs, wasm_modulesNot supportedNothingImport the file from the Worker source instead.
Other binding typesNot supportedNothingIncludes other unsafe binding types.
  • Configuration that changes how the Worker runs, not what env contains, still stops orange dev with Unsupported Wrangler configuration.
  • Examples are streaming_tail_consumers and triggers.events.
  • orange dev accepts containers with a warning and runs @cloudflare/sandbox classes on a sandbox provider, such as E2B, Daytona, or Freestyle (see Sandbox).
  • orange dev runs triggers.crons (see Cron Triggers) and delivers queues.consumers to the Worker’s queue() handler (see Queues).

Bindings that are not supported

orange dev marks each binding that is not supported in its binding table at startup, with what to use instead on the next line:

  Binding        Resource            Runs on
! env.IMAGES     Images              stub · calls throw
                                     See the OpenOrange bindings documentation for supported bindings.

The binding is a stub, and it is safe to pass around. typeof env.IMAGES is "object", reading a property returns a function, and awaiting the stub does not call it. Calling any method throws an Error with the same message:

await env.IMAGES.info(stream);
// Error: Images binding "IMAGES" is not supported by OpenOrange. ...

What to use instead

Most bindings that are not supported have a replacement. Most replacements use fetch() to an external service, or a Durable Object, which OpenOrange runs as a Rivet Actor with SQLite storage and alarms.

Other bindings

OpenOrange does not support these bindings. Change the Worker to call one of these services instead:

BindingService to use insteadHow the Worker reaches it
Vectorizepgvector on Neon or SupabaseA Hyperdrive binding and a Postgres driver
VectorizeQdrant Cloudfetch() to https://<cluster host>:6333, with the api-key header
VectorizePineconefetch() to the index host, with the Api-Key header
Vectorize, a few thousand vectorsSQLite in a Durable ObjectStore the embeddings, and rank them by cosine similarity in JavaScript
ImagesCloudinaryfetch() to its upload and transformation URLs
Imagesimgproxy that you runfetch() to its processing URLs
Analytics EngineYour analytics storefetch() to its ingest API

Variables and secrets

orange dev resolves variables with Wrangler’s own wrangler dev logic:

  1. It starts with vars from the Wrangler configuration.
  2. It loads .dev.vars.<env> or .dev.vars next to the configuration file.
  3. If neither file exists, it loads .env, .env.local, .env.<env>, and .env.<env>.local. Set CLOUDFLARE_INCLUDE_PROCESS_ENV=true to also load the process environment.
  4. Loaded values become string bindings that replace vars with the same name.
  5. If secrets.required is set, only the listed keys load, and orange dev warns about missing keys.

A .dev.vars entry named after another binding, such as a Secrets Store binding, stays that binding’s local value and does not replace it.

Secret values never become part of the version metadata ID.

Compatibility

From the latest conformance run. Scores on the compatibility page; every binding on the status page.

Analytics Engine

Partial analytics_engine_datasets

Runs on A dataset that drops every data point, as Miniflare does.

writeDataPoint() succeeds and stores nothing. There is no SQL API to query.

In the feature matrix

Partialanalytics_engine_datasets (analytics_engine)Writes data points to a Workers Analytics Engine dataset.writeDataPoint() accepts data points and drops them, as Miniflare does in local development. 0/1 pass · 4 files
Notes
There is nothing to query. Upstream analytics-engine-test still fails because the conformance runner drops its binding.
Workaround
Write data points to a Durable Object or D1 database if you need to read them back.
Tests
  • api-tests--analytics-engine-test › main Error: Test never received request from analytics engine handler Fail · Behavior differs
Source
packages/runtime-node/src/bindings/analytics-engine.ts:1-6src/config/load-wrangler.ts:838-839packages/runtime-node/src/runner.ts:460-462src/commands/dev.test.ts:499-547