Skip to content

What runs when you type $ openorange deploy

Three layers: your code, a runtime that speaks the Workers API, and Rivet for everything stateful. All of it runs in your cloud account.

How OpenOrange moves a Cloudflare project into your datacenter wrangler dev becomes openorange dev, then openorange deploy. Your Cloudflare project leaves Cloudflare and lands in your datacenter as a stack: the project, unchanged, on the OpenOrange runtime, on Rivet, on AWS, GCP, Azure or on-prem. $ wrangler dev openorange dev $ openorange deploy Cloudflare Your datacenter · AWS · GCP · Azure · on-prem OpenOrange runtime Rivet open-source control plane unchanged Workers Durable Objects KV · Queues · Workflows D1 · R2 · Cron Your Cloudflare project

Service map

Cloudflare OpenOrange Status Notes
Workers OpenOrange runtime Drop-in The Workers API surface (fetch handler, env bindings, waitUntil, Cache) on Node.js. Your code and wrangler config load unchanged.
Durable Objects Rivet Actors Partial One Rivet Actor per object, with SQLite storage and alarms. Same class, same bindings. WebSocket hibernation is emulated: the object leaves memory, and its actor keeps running.
Workers KV Actor-backed KV Drop-in The KV binding API, one Actor per namespace. Strongly consistent instead of eventually.
Queues Actor-backed queues Drop-in Producers and consumers keep the Queues API, with batching, retries and dead-letter queues. One batch runs at a time per queue.
Workflows Cloudflare's own Workflows engine Partial The engine that wrangler dev runs, copied from @cloudflare/workflows-shared, with one Rivet Actor per instance. Steps, sleeps, events and retries work. instance.subscribe() is not available.
Cron Triggers Actor schedules Drop-in Same cron syntax in your config. Crons fire in orange dev too.
D1 SQLite on Rivet Drop-in The D1 binding API on one SQLite database in a Rivet Actor.
R2 A Rivet Actor, or your S3-compatible store Pluggable A bucket is an Actor by default. Point it at any S3-compatible store instead.
Workers AI An OpenAI-compatible provider Pluggable The AI binding calls any OpenAI-compatible endpoint you already pay for. Text and embedding models.
Sandboxes Your sandbox provider Pluggable The Sandbox SDK runs on a hosted provider, an agentOS VM or a local directory. Other Container images are not run.
Hyperdrive Direct connection Drop-in Works unchanged. You are already in the VPC, so env.HYPERDRIVE passes the connection string straight through.
Browser Run Your browser Pluggable @cloudflare/puppeteer drives your Chrome or a hosted browser over the DevTools Protocol.
Email Your SMTP server Pluggable send_email sends through your SMTP server. Inbound mail reaches email() from your provider's webhook.
Vectorize, Images, Pipelines Bring your own Not supported The bindings load and every call throws. Call a replacement such as pgvector with fetch() today.

Drop-in: the binding API works unchanged. Pluggable: the binding works unchanged and you choose the backend. Partial: it runs, but some documented APIs throw or act differently. Not supported: calls throw.

The runtime: Workers APIs on Node.js

A Cloudflare Worker is a module with a fetch handler, some optional scheduled, queue and email handlers, and an env object full of bindings. OpenOrange starts a Node.js process for each Worker, loads your module, and hands it an env whose bindings are backed by OpenOrange instead of Cloudflare.

Request, Response, fetch, WebSocketPair, Cache, waitUntil and the rest of the Workers globals are installed by the runtime. Most node: imports are stock Node.js; the few modules whose behaviour differs on Cloudflare, such as node:process and node:buffer, are swapped for workerd-shaped versions so your code behaves the same.

Configuration comes from the wrangler.toml or wrangler.jsonc you already have. Bindings, Durable Object classes and migrations, cron triggers, queues and vars are read from it. Environment-specific overrides map to OpenOrange environments.

Durable Objects become Rivet Actors

A Durable Object is a class with a globally unique ID, single-threaded execution, transactional storage, alarms and WebSocket hibernation. A Rivet Actor has the same shape, so each Durable Object runs as one Rivet Actor.

Rivet is an open-source control plane. When your Worker calls env.ROOM.get(id).fetch(), Rivet locates the Actor for that ID, wakes it on one of your instances if it is asleep, and routes the request. The storage API, SQLite storage and alarms are backed by Rivet durable state. WebSocket hibernation is emulated: after 10 idle seconds the object leaves memory and its sockets stay open, and the next message builds a new instance. The Actor keeps running while a socket is open.

Actors share the memory of the machine they run on, and you can inspect their state and connections from the Rivet dashboard.

KV, Queues, Workflows, D1 and cron

Each of these is a thin binding over Actors. Each KV namespace is one Actor, which makes it strongly consistent rather than eventually. Each queue is one Actor; retries and dead-letter queues follow Cloudflare, and a queue delivers one batch at a time. Workflows run on Cloudflare's own Workflows engine, with one Actor per instance: durable steps, sleeps and retries without a per-step CPU budget. Cron triggers become Actor schedules. Each D1 database is one Actor's SQLite database.

R2, Workers AI, Sandboxes, Browser Run and Email plug into your providers

Some Cloudflare services are front doors to things you can already buy elsewhere. An R2 bucket is an Actor by default, and one environment variable points it at any S3-compatible store, such as Amazon S3, Google Cloud Storage or MinIO. The AI binding calls any OpenAI-compatible endpoint, OpenRouter by default. The sandbox binding targets E2B, Daytona, Freestyle, an agentOS VM or a local directory. Browser Run drives your Chrome or a hosted browser over the DevTools Protocol, and Send Email goes through your SMTP server.

Where state lives

On Rivet Cloud and BYOC, Rivet operates the durable store for you. Self-hosted, Rivet persists Actor state to Postgres or FoundationDB that you run. In every case the data is in the cloud account and region you chose, reachable only inside your network unless you expose it.

Deploys, upgrades and observability

openorange deploy builds a container image of your project and the runtime, pushes it, and rolls it out through Rivet. When a runtime stops, it closes each accepted WebSocket with 1012 Service Restart so that clients reconnect, and its Actors wake on the new version. You choose when a deploy happens.

RivetKit serves metrics on RIVETKIT_METRICS_PORT. The Rivet dashboard adds an Actor list, a state inspector, a connection inspector and an RPC debugger.

What you need to know about Rivet

Not much. Rivet is the engine underneath; OpenOrange is the Cloudflare-shaped interface on top of it. You interact with the openorange CLI and your wrangler config. Rivet shows up when you choose where to deploy (Rivet Cloud, your VPC, or self-hosted) and when you open the dashboard.

If you want to go further, every Durable Object you migrate is now a Rivet Actor, and the rest of the Rivet ecosystem (the Actors SDK, Workflows, agent runtimes) is available alongside your Workers code.

Deeper reading: Rivet Actors, Rivet deployment, Rivet Actors vs Durable Objects, workerd vs OpenOrange, compatibility scores, bindings.

Keep the platform. Lose the walls.

Your Cloudflare project in your datacenter.

Built for serious scale.