How the denoland/celld Project Is Structured: A Deep Dive Into the Rust Workspace Architecture

The denoland/celld project uses a single-crate Cargo workspace with three distinct layers: a pure logic core for state-machine decisions, an effect executor for V8 and I/O operations, and an LTX crate for replicated SQLite log records.

celld is Deno's open-source implementation of Cloudflare Durable Objects—a distributed, self-hosted alternative that lets you run JavaScript Workers with durable state. Understanding how the project is structured helps contributors navigate the codebase and operators deploy it effectively. The repository follows a strict separation between deterministic logic and runtime effects, making the system testable and the core formally verifiable.

The Three-Crate Workspace Architecture

The Cargo.toml at the repository root declares resolver = "2" and three member crates under [workspace.members]: logic, celld, and ltx. All dependencies are centralized in [workspace.dependencies] to ensure version consistency across the entire project.

This structure prevents version drift and makes the build reproducible across CI, development, and production environments.

The Logic Crate: Pure Deterministic State Machine

The crates/logic directory contains the decision core—a side-effect-free state machine implementing Durable Objects semantics. No I/O, no async, no V8—just pure Rust functions that transform state.

Key characteristics:

The core types include State, Cell, and Phase. When the runtime needs to advance a cell's state, it calls logic::on_event with an event and receives a list of effects to execute.

Example: creating and inspecting a State:

use celld_logic::{State, Config};

fn demo() {
    let config = Config::default();
    let mut state = State::new("node-1", config);

    println!("Resident cells: {}", state.residents().len());

    for (phase, count) in state.phase_census() {
        println!("{phase}: {count}");
    }
}

This mirrors the public API exposed by crates/logic/lib.rs. The guarantees documented in docs/guarantees.md are enforced entirely within this crate.

The Celld Crate: Effect Executor and Runtime Adapter

The crates/celld directory hosts the effect adapter—everything that touches the outside world. This crate bridges the pure logic core to actual execution.

Responsibilities include:

  • V8 isolates: Running JavaScript Workers in sandboxed contexts
  • HTTP/WebSocket handling: External API surface for client requests
  • Bucket I/O: Reading and writing durable state to S3, GCS, or Azure
  • Peer-to-peer RPC: Internal communication between fleet nodes
  • Telemetry: Metrics and observability exports
  • CLI: Binary entry point and command-line interface

The main entry point is [crates/celld/main.rs](https://github.com/denoland/celld/blob/main/crates/celld/main.rs). The celld::cli module parses flags and constructs a State via logic::State::new, then drives the event loop.

Typical CLI workflow:


# Run a single-node dev instance (no bucket needed)

celld dev

# Deploy to production bucket

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

# Start a fleet node

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

When an external event arrives, the celld crate calls logic::on_event, receives effects (like "send HTTP response" or "write to bucket"), and executes them.

The LTX Crate: Replicated Log-Record Format

The crates/ltx directory implements the log-record (LTX) format—the foundation for durability and replication across the fleet.

Components include:

LTX records represent SQLite write transactions that must be replicated between nodes. The format enables eventual consistency with strong ordering guarantees—critical for maintaining serializable semantics across the distributed system.

Entry point: [crates/ltx/src/lib.rs](https://github.com/denoland/celld/blob/main/crates/ltx/src/lib.rs)

Supporting Directories

Examples Directory

The examples/ folder contains minimal Worker projects demonstrating celld capabilities:

Run with celld dev locally or celld deploy . to production.

Documentation

The docs/ directory hosts human-readable guides:

The root [README.md](https://github.com/denoland/celld/blob/main/README.md) provides installation and quick-start instructions.

Design Philosophy: Why This Structure Matters

The denoland/celld project structure enables three critical properties:

  1. Testability: The logic crate runs in pure Rust tests with mocked time and events—no V8 or network required
  2. Correctness: The state machine can be fuzzed, model-checked, or formally verified because it has no I/O
  3. Portability: The effect adapter can be swapped for different environments (embedded, serverless, edge) without touching core semantics

This separation mirrors the command pattern: logic decides what should happen, celld makes it happen, and ltx ensures it survives failures.

Summary

  • crates/logic — Pure state machine with on_event entry point; handles all Durable Objects semantics deterministically
  • crates/celld — Effect executor with V8, HTTP, bucket I/O, and CLI; bridges logic to runtime
  • crates/ltx — Replicated log format for SQLite transactions; codecs, cloud storage clients, and compaction
  • Cargo.toml — Workspace root with unified dependencies and resolver v2
  • examples/ — Runnable Worker demonstrations
  • docs/ — User-facing documentation including guarantees and operational guides

All core logic resides in three interconnected crates, with clear boundaries that prevent coupling between decision-making and execution.

Frequently Asked Questions

What is the entry point for the celld binary?

The binary entry point is [crates/celld/main.rs](https://github.com/denoland/celld/blob/main/crates/celld/main.rs). This file initializes the CLI parser, constructs a logic::State, and starts the async runtime. It delegates to celld::cli for argument handling and logic::on_event for state transitions.

How does celld achieve deterministic execution?

Determinism lives entirely in crates/logic. The State struct and on_event function perform no I/O, use no randomness, and depend only on input events and configuration. This makes the core replayable and testable. Non-determinism—timers, network, V8—is isolated in crates/celld as effects that the logic core requests but does not execute.

Can I use the logic crate independently?

Yes. The celld_logic crate exposes a library API for embedding. You can construct a State with Config, drive it with on_event, and handle effects yourself. This is documented in docs/library-api.md. The separation exists specifically to support alternative runtimes and testing frameworks.

What is LTX and why does it need its own crate?

LTX (Log-Transaction-something) is the on-disk format for replicated SQLite writes. It needs its own crate because both celld (for writing) and external tools (for inspection, backup, compaction) depend on it. The ltx crate provides codecs, object store abstractions, and compaction logic without depending on the full celld runtime or V8.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →