# How celld Achieves Cloudflare Workers and Durable Objects API Compatibility

> Discover how celld achieves Cloudflare Workers and Durable Objects API compatibility by embedding V8, implementing SQLite-backed cells, and exposing the full Workers surface.

- Repository: [Deno/celld](https://github.com/denoland/celld)
- Tags: architecture
- Published: 2026-08-09

---

**`celld` reproduces the Cloudflare Workers runtime and Durable Objects API by embedding V8 to execute Wrangler-bundled modules, implementing Durable Objects as isolated SQLite-backed cells with S3 replication, and exposing the full Workers surface including RPC, alarms, and WebSockets through a JavaScript harness.**

The `denoland/celld` project provides a self-hosted runtime that achieves complete Cloudflare Workers and Durable Objects API compatibility without relying on Cloudflare's infrastructure. By combining a V8-based JavaScript engine with a bespoke storage layer and distributed ownership protocol, celld enables developers to deploy existing Workers applications to any infrastructure while maintaining the exact semantics of Durable Objects state management and coordination.

## V8-Based Workers Runtime Engine

Each celld node embeds V8 to execute JavaScript modules bundled by Wrangler, exposing the complete Workers runtime surface. In [`crates/celld/runtime.rs`](https://github.com/denoland/celld/blob/main/crates/celld/runtime.rs), the runtime bridges the V8 isolate with Rust to handle module loading, providing standard APIs including `fetch`, environment variables, and service bindings. This implementation matches the compatibility specifications documented in [`docs/cloudflare-compat.md`](https://github.com/denoland/celld/blob/main/docs/cloudflare-compat.md), ensuring that standard Web Platform APIs and Workers-specific features behave identically to Cloudflare's production environment.

The runtime executes Wrangler-bundled modules directly, requiring only `esbuild` available on `PATH` during the build phase. This approach allows existing Workers projects to migrate without code changes, as celld handles the exact same module formats and global scope expectations.

## Durable Object Cell Architecture

At the core of celld's Durable Objects implementation is the **cell** abstraction. Every Durable Object class is instantiated as a cell with isolated state management, replicating the semantics of Cloudflare's single-owner, single-threaded execution model.

### SQLite-Backed State Management

Cell state persists in isolated SQLite databases managed by [`crates/celld/storage.rs`](https://github.com/denoland/celld/blob/main/crates/celld/storage.rs). The `DurableObjectStorage` implementation in [`crates/celld/js/harness.js`](https://github.com/denoland/celld/blob/main/crates/celld/js/harness.js) provides the exact storage API expected by Cloudflare, including transactional `get`, `put`, `delete`, and `list` operations. This JavaScript harness wraps the Rust storage layer, exposing the familiar `this.state.storage` interface to Durable Object classes.

```js
export class Counter extends DurableObject {
  async fetch(request) {
    const value = await this.state.storage.get('val') ?? 0;
    await this.state.storage.put('val', value + 1);
    return new Response(`${value + 1}`);
  }
}

```

The `DurableObject` base class referenced above is provided by [`harness.js`](https://github.com/denoland/celld/blob/main/harness.js), ensuring that class inheritance and lifecycle methods match Cloudflare's implementation exactly.

### Replication and Ownership Protocol

Cells replicate to an S3-compatible bucket using the protocol defined in [`crates/celld/protocol.rs`](https://github.com/denoland/celld/blob/main/crates/celld/protocol.rs). Rather than implementing a distributed consensus algorithm, celld uses object-storage compare-and-swap operations to establish ownership. This guarantees that at most one node owns a cell at any moment, providing the same single-threaded execution guarantees as Cloudflare's Durable Objects without requiring additional coordination services.

When a node needs to process a request for a specific Durable Object, it attempts to acquire ownership through the bucket protocol. If successful, it loads the cell's SQLite database from S3 and processes the request; otherwise, it redirects or queues the request appropriately.

## Complete API Surface Implementation

Beyond basic storage and compute, celld implements the extended Durable Objects API surface including coordination primitives and real-time communication.

### Alarms and WebSocket Support

The runtime implements Durable Object alarms through the `alarm` handler, allowing scheduled execution exactly as Cloudflare does. For real-time communication, celld supports inbound hibernatable WebSockets and outbound `ws:`/`wss:` clients, maintaining the same connection semantics and state restoration patterns documented in [`docs/cloudflare-compat.md`](https://github.com/denoland/celld/blob/main/docs/cloudflare-compat.md).

### JavaScript RPC System

`celld` ships with the same JS RPC system used by Cloudflare Workers, including `WorkerEntrypoint`, `RpcTarget`, and Durable Object stubs. The implementation serializes calls using structured-clone semantics and pipelines them across isolates. This enables method invocation on Durable Objects using standard JavaScript class patterns rather than HTTP requests, matching the behavior described in the compatibility documentation.

```js
export default {
  async fetch(request, env) {
    const counterId = env.COUNTER.idFromName('global');
    const counter = env.COUNTER.get(counterId);
    const resp = await counter.fetch(new Request('https://example/'));
    return new Response(`Counter: ${await resp.text()}`);
  },
};

```

The `env.COUNTER` binding is automatically populated by `celld` when the Worker declares the class in [`wrangler.json`](https://github.com/denoland/celld/blob/main/wrangler.json), exposing the same stub interface used in Cloudflare's environment.

## CLI and Deployment Workflow

The `celld deploy` command builds Wrangler projects and writes the compiled bundle directly into the configured S3 bucket. Nodes automatically pull the latest [`deploy/current.json`](https://github.com/denoland/celld/blob/main/deploy/current.json) on startup, enabling seamless rolling deployments across a cluster.

```bash

# Build and upload the bundle

celld deploy . --bucket s3://my-cells-bucket

# Start a node that will run the Worker

celld \
  --bucket s3://my-cells-bucket \
  --listen 0.0.0.0:8080 \
  --advertise node-a.internal:8080

```

This deployment model eliminates the need for a centralized control plane. The bundle written to [`deploy/current.json`](https://github.com/denoland/celld/blob/main/deploy/current.json) contains the complete Worker code, which each node loads into its V8 isolate upon initialization.

## Summary

- **`celld` embeds V8** to execute Wrangler-bundled Workers modules with full API compatibility.
- **Durable Objects are implemented as cells** with SQLite-backed storage in [`crates/celld/js/harness.js`](https://github.com/denoland/celld/blob/main/crates/celld/js/harness.js) and [`crates/celld/storage.rs`](https://github.com/denoland/celld/blob/main/crates/celld/storage.rs).
- **S3-compatible object storage** handles replication and ownership via compare-and-swap operations defined in [`crates/celld/protocol.rs`](https://github.com/denoland/celld/blob/main/crates/celld/protocol.rs).
- **Extended APIs** including alarms, WebSockets, and JS RPC match Cloudflare's implementation details.
- **Self-hosted deployment** uses `celld deploy` to write bundles directly to object storage, with nodes pulling configuration automatically.

## Frequently Asked Questions

### Is celld a drop-in replacement for Cloudflare Workers?

Yes. According to the `denoland/celld` source code, the runtime implements the full Workers and Durable Objects API surface documented in [`docs/cloudflare-compat.md`](https://github.com/denoland/celld/blob/main/docs/cloudflare-compat.md). Existing Wrangler projects build without modification, and Durable Object classes use identical syntax and semantics, including `state.storage` operations and RPC methods.

### How does celld handle Durable Object state persistence?

Each Durable Object instance (cell) maintains state in an isolated SQLite database managed by [`crates/celld/storage.rs`](https://github.com/denoland/celld/blob/main/crates/celld/storage.rs). The JavaScript harness in [`crates/celld/js/harness.js`](https://github.com/denoland/celld/blob/main/crates/celld/js/harness.js) exposes this through the standard `DurableObjectStorage` interface, providing transactional consistency for `get`, `put`, and `delete` operations. State automatically replicates to the configured S3-compatible bucket.

### What infrastructure is required to run celld?

`celld` requires only an S3-compatible object storage bucket for deployment artifacts and cell state replication. Nodes run as standalone binaries that embed V8 and communicate directly with the storage backend. No Kubernetes, consensus clusters, or Cloudflare-specific services are necessary, though `esbuild` must be available on the deployment host's `PATH`.

### How does celld ensure single-owner semantics without consensus protocols?

The system uses object-storage compare-and-swap operations to establish cell ownership, as implemented in [`crates/celld/protocol.rs`](https://github.com/denoland/celld/blob/main/crates/celld/protocol.rs). This guarantees that at most one node can own a Durable Object cell at any time, providing the same execution guarantees as Cloudflare's infrastructure without requiring Raft, Paxos, or other distributed consensus mechanisms.