What Is the Primary Purpose of the denoland/celld Repository?
The denoland/celld repository provides a self-hosted, stateful, distributed runtime for server-side JavaScript that replicates Cloudflare Workers + Durable Objects on your own infrastructure.
Celld lets you run JavaScript "cells"—isolated, durable compute units with private SQLite databases—without depending on proprietary cloud platforms. As implemented in denoland/celld, every cell persists its long-term state to a user-controlled object bucket (S3-compatible, Google Cloud Storage, or Azure Blob), giving you full ownership of your data and deployment environment.
Understanding the Celld Architecture
What Is a Cell?
A cell is the fundamental unit of computation in celld. According to the source documentation at docs/README.md, each cell encapsulates:
- A small server with a private SQLite database
- HTTP request handling
- WebSocket connection persistence
- Alarm scheduling for delayed tasks
- Outbound network calls
This design directly mirrors Cloudflare Durable Objects, but runs entirely on infrastructure you control.
Fleet-Based Distribution
Multiple celld nodes form a fleet that shares the same storage bucket. In docs/README.md, the architecture specifies that any node can claim and serve any cell. The bucket itself mediates ownership through conditional writes, ensuring that only one node actively serves a given cell at any time.
This approach enables:
- Horizontal scaling across machines
- Zero-downtime failover when nodes restart or fail
- Geographic distribution without cloud vendor lock-in
Durability Guarantees
Celld offers RPO = 0 (zero Recovery Point Objective) durability, meaning no committed data is lost on node failure. The system supports configurable durability modes as documented in docs/README.md:
| Mode | Behavior |
|---|---|
| Fleet durability | State replicated across fleet nodes |
| Bucket durability | State written directly to object storage |
Getting Started with Celld
The repository includes practical tooling to run cells locally and in production. The entry point at crates/celld/main.rs handles node initialization, listeners, and runtime management.
Installation and Local Development
# 1️⃣ Install the celld binary (once)
curl -fsSL https://celld.dev/install.sh | sh
# 2️⃣ Run a local development node for the example counter app
git clone https://github.com/denoland/celld
cd celld/examples/counter
celld dev # starts a node on http://127.0.0.1:9876
# 3️⃣ Interact with the counter cell (the Durable Object) via curl
curl http://127.0.0.1:9876/ # → {"count":0}
curl -X POST http://127.0.0.1:9876/incr # increments the counter
curl http://127.0.0.1:9876/ # → {"count":1}
The celld dev command launches a single-node fleet for local testing. Production deployments use celld run with environment-specific configuration for your object bucket.
Core Implementation Files
| File | Responsibility |
|---|---|
crates/celld/main.rs |
Binary entry point—node setup, listeners, runtime manager |
crates/logic/lib.rs |
Cell routing, storage, alarms, and replication logic |
docs/README.md |
Architecture documentation and deployment concepts |
examples/counter/index.js |
Minimal stateful cell implementation |
The core logic in crates/logic/lib.rs implements the distributed systems primitives: cell claiming, state checkpointing to object storage, alarm scheduling, and cross-node coordination.
Example Cell Implementation
Here's how a simple counter cell works, based on examples/counter/index.js:
// A cell maintains state across HTTP requests
let count = 0;
export default {
async fetch(request) {
const url = new URL(request.url);
if (url.pathname === "/incr" && request.method === "POST") {
count++;
return new Response(JSON.stringify({ count }), {
headers: { "Content-Type": "application/json" }
});
}
return new Response(JSON.stringify({ count }), {
headers: { "Content-Type": "application/json" }
});
}
};
The count variable persists across requests because the cell process remains alive. For durability across restarts, celld automatically checkpoints SQLite state to your configured bucket.
Summary
- Celld replicates Cloudflare Workers + Durable Objects as open-source, self-hosted infrastructure
- Cells combine JavaScript execution, SQLite storage, HTTP/WebSocket serving, and alarms in one unit
- Fleet architecture with object bucket coordination enables distributed, fault-tolerant deployment
- Configurable durability modes balance performance against persistence guarantees
- All state ultimately resides in user-controlled object storage (S3, GCS, or Azure Blob)
Frequently Asked Questions
How does celld differ from running Node.js with PM2?
Celld provides granular, addressable stateful units (cells) with built-in durability, not just process management. Each cell has its own SQLite database, automatic checkpointing to object storage, and cluster-wide coordination via conditional writes. PM2 manages processes; celld manages distributed, migratable, durable compute with zero-downtime failover.
Can I run celld without any cloud provider?
Yes. Celld only requires an S3-compatible object store, which you can self-host using MinIO, Ceph, or similar on your own hardware. The compute nodes themselves run wherever you have Linux machines—bare metal, VMs, or Kubernetes clusters.
What happens when a celld node crashes?
The bucket decides ownership via conditional writes. When a node fails, another node in the fleet detects the expired claim, conditionally writes a new ownership record, and resumes serving the cell from the last checkpoint. The system achieves RPO = 0 durability when bucket durability mode is enabled.
Is celld production-ready?
As of the main branch in denoland/celld, the project is actively developed by the Deno team with documented architecture, example applications, and installation tooling. Evaluate against your specific requirements—particularly regarding the maturity of the Rust-based logic layer in crates/logic/lib.rs—before deploying critical workloads.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →