RepoDaily · 2026-08-08 · Self-hosted app

denoland/celld Brings Durable Objects to Self-Hosted Infrastructure

#9 Self-hosted app Rust +546 denoland/celld Open repository

A Rust runtime that embeds V8 to run stateful, single-threaded Durable Objects on your own machines, with object-store persistence and Apache-2.0 licensing.

Repo typeSelf-hosted app
Best forDevelopers who want Cloudflare-style stateful actors without a managed edge platform
Risk levelHigh — early project with no published stability or API guarantees
Time to evaluate4–6 hours to build and run a local instance

Primary question: Does your workload need single-threaded stateful objects that survive restarts on infrastructure you control?

83/100

RepoDaily adoption score

RepoDaily rates this as 83/100 (strong) for adoption: evidence, installation path, production risk, differentiation, license clarity, and AI/agent fit are scored from the article sources and adoption notes.

Directional score from RepoDaily sources and adoption notes, not a benchmark.Risk: High
96Evidence quality

4 source(s) across 3 source category/categories, plus a RepoDaily-specific evidence module when available.

100Installability

5 workflow step(s), 4 next-action step(s), and 3 command/install signal(s) were detected.

54Maintenance confidence

Trending momentum is +546 stars, with maintenance/release/issue signals counted when present.

75Production readiness

Risk is marked high, with 5 security note(s) and 3 explicit skip condition(s).

97Differentiation

2 opportunity lens item(s), 4 alternative(s), and 3 type-specific section(s) support differentiation.

82License clarity

License source or license wording is present.

66Agent / AI fit

3 AI/agent-related signal(s) were detected in the article text and metadata.

Project overview

denoland/celld is a self-hosted, distributed implementation of Durable Objects written in Rust. Cloudflare coined the Durable Object pattern for stateful, single-threaded actors that run on edge infrastructure; celld ports that model to machines you own. The project earned 546 stars during this trend window and ranks #9 on RepoDaily's trending list for 2026-08-08.

The repository is structured as a Cargo workspace. The workspace Cargo.toml states that `crates/logic` owns all behavioral state and decisions while `crates/celld` acts as an effect executor and adapter host. A third crate, `crates/ltx`, is referenced as a path dependency. This separation means the runtime logic and the side-effect layer (network, storage, V8 host) are designed to evolve independently.

celld embeds V8 at version 152, listed as a direct workspace dependency alongside tokio, axum, hyper, fastwebsockets, and rustls. The inclusion of `object_store` 0.11 and `rusqlite` 0.31 indicates that persistence can target both S3-compatible object storage and local SQLite. The crypto stack — aes-gcm, ed25519-dalek, p256, rsa, hmac — suggests request signing and encrypted state are first-class concerns.

The project is licensed under Apache 2.0 and ships a Dockerfile based on `rust:1.97.1-bookworm`. The Docker build runs `cargo test --release --locked` and `cargo clippy --release --all-targets --locked -- -D warnings` in a dedicated test stage, which means a lint or test failure stops a release candidate before the final image is produced.

Problem it solves

  • Durable Objects on Cloudflare require you to run on Cloudflare's edge; teams with data-residency, latency, or vendor-lock-in constraints cannot use them directly.
  • Building a stateful actor runtime from scratch requires solving persistence, replication, single-writer semantics, and isolation — problems most application teams should not solve themselves.
  • Existing self-hosted stateful platforms (Redis, Temporal) target different abstractions: key-value or workflow orchestration, not single-threaded objects with request-scoped handlers.

How it works

  1. The celld binary is built from the workspace and packaged into a `debian:bookworm-slim` image whose entrypoint is `/usr/local/bin/celld`.
  2. The runtime embeds V8 (`v8 = "152"`) to execute JavaScript inside isolated contexts, consistent with Deno's existing engine strategy.
  3. `crates/logic` holds all behavioral decisions; `crates/celld` executes side effects such as WebSocket upgrades (`fastwebsockets` with axum), HTTP serving (hyper/axum), and TLS (rustls with the ring provider).
  4. State is persisted through `object_store` 0.11 (S3-compatible backends) and `rusqlite` 0.31 (local SQLite), giving operators a choice between cloud object storage and on-disk durability.
  5. The `lab` Cargo profile (`lto = "thin"`, `codegen-units = 16`, `incremental = true`) provides a fast development loop; shipped artifacts always build with the `release` profile (`fat` LTO, `opt-level = "s"`, `panic = "abort"`, `strip = true`).

Architecture Read: Logic Crate vs Effect Executor

The workspace Cargo.toml explicitly states that `crates/logic` owns all behavioral state and decisions and `crates/celld` is only an effect executor and adapter host. This is a deliberate hexagonal-architecture split: the decision engine has no direct dependency on the network or storage adapter, which makes the logic testable in isolation.

Direct workspace dependencies confirm the adapter surface: `axum` 0.7 with multipart for HTTP, `fastwebsockets` 0.8 with the `with_axum` feature for real-time connections, `hyper` 1 for client and server HTTP/1, and `tokio-rustls` 0.26 with the ring crypto provider for TLS. `object_store` 0.11 is pulled in with default features disabled, meaning the operator selects the storage backend rather than inheriting all provider implementations.

Deployment Notes from the Dockerfile

The Dockerfile pins Rust 1.97.1 on `rust:1.97.1-bookworm` and supports an architecture argument (`TARGETARCH`) with per-architecture target cache mounts. A build argument `CELLD_PROFILE` selects between the `release` profile (default, shipped artifacts) and the `lab` profile, which a caller can pass to skip the fat-LTO relink.

The test stage adds the `clippy` component and runs `cargo test --release --locked` followed by `cargo clippy --release --all-targets --locked -- -D warnings`. The `-D warnings` flag means any clippy lint is treated as a hard error, so the release pipeline rejects code that does not pass the project's lint bar.

The final runtime image is `debian:bookworm-slim` with only `ca-certificates` added beyond the base package set. The OCI labels include `org.opencontainers.image.title`, `revision`, and `version`, which integrates with registries that surface OCI metadata.

Maintenance and Maturity Risk

The project carries no homepage URL, no topic tags, and the README-derived metadata consists of a single description line: `self-hosted, distributed Durable Objects`. There is no published stability contract, API reference, or deployment guide visible in the source pack.

Dependency versions are recent (`tokio` 1, `axum` 0.7, `hyper` 1, `v8` 152, `rustls` 0.23, `object_store` 0.11), which means the codebase tracks current Rust ecosystem releases but also that breaking changes in upstream crates will require active maintenance to absorb.

Who should pay attention?

Good fit if

  • Teams evaluating a self-hosted alternative to Cloudflare Durable Objects for data-residency or latency reasons.
  • Infrastructure engineers who already operate Rust services and want a V8-embedded actor runtime they can inspect and patch.
  • Prototypes that need single-writer stateful objects backed by S3-compatible storage or local SQLite.

Skip for now if

  • Projects that only need key-value caching — Redis or DragonflyDB are simpler.
  • Teams without Rust operational experience who require a vendor SLA or managed control plane.
  • Workloads that already fit Cloudflare Workers/Durable Objects and have no constraint forcing them off the managed edge.

Risks and cautions

High

The project has no published API documentation, no release notes, and a minimal README. Adoption today is a research-grade commitment, not a drop-in platform.

  • The README metadata is a single description line with no topics, homepage, or deployment guide.
  • No version tags, changelog, or stability guarantees are visible in the source pack.
  • The workspace pins recent crate versions (axum 0.7, hyper 1, v8 152) that can introduce breaking changes between updates.
  • Distributed semantics — replication, failover, consistency — are not described in the available sources.
  • The runtime embeds V8 152, which receives Chromium security updates; operators must rebuild celld to pick up V8 patches.
  • TLS is provided by rustls 0.23 with the ring provider; the `ring` feature is explicitly selected over aws-lc-rs.
  • The crypto stack includes aes-gcm 0.10, ed25519-dalek 2, p256 0.13, and rsa 0.9, indicating request and state cryptography are in scope.
  • The final Docker image ships only ca-certificates beyond the debian-slim base, reducing the attack surface of the runtime container.
  • No CVE feed, security policy, or disclosure process is visible in the source pack.

Alternatives to compare

ApproachWhen to useTrade-off
Cloudflare Durable Objects
You want the original managed implementation with no infrastructure to run.Usage-based pricing on Cloudflare Workers
Temporal
You need durable workflow orchestration rather than single-threaded stateful objects.Open source (MIT) or managed Temporal Cloud
Redis
Your workload is primarily key-value or pub/sub and does not need JavaScript actors.Open source (RSF/SSPL) or Redis Cloud
Litestream
You want SQLite replication without an actor abstraction on top.Open source (Apache-2.0)

What this trend reveals

Self-hosted real-time collaboration backends

The combination of fastwebsockets, single-writer Durable Object semantics, and object_store persistence maps directly onto collaborative editing or presence features that teams currently route through Cloudflare.

Write a celld object that holds a document state, accept WebSocket connections, and measure failover time when the backing object_store target is unreachable.

Air-gapped stateful actors

Because celld runs on your own hardware with local SQLite via rusqlite, it can serve regulated environments where data cannot leave the deployment boundary.

Build the Docker image offline, run it with a local rusqlite store, and confirm no outbound network calls are required for object execution.

Best next action

Build the image and trace one object lifecycle

The fastest way to assess celld is to build the Docker image locally and inspect the binary surface, since no hosted trial exists.

  1. Clone the repository and run `docker build -t celld:local .` using the provided Dockerfile.
  2. Inspect the two-stage test gate to confirm clippy with `-D warnings` passes on your machine.
  3. Run the `celld` binary with `--help` (or equivalent) to enumerate the configuration flags the adapter host exposes.
  4. Trace the `crates/logic` crate to see which behavioral decisions are unit-testable without the effect executor.

RepoDaily verdict

denoland/celld is a credible Rust/V8 reimagining of Durable Objects for self-hosted infrastructure, but it is early: no API docs, no release contract, and no published distributed-semantics guarantee. Treat it as a research-grade platform to prototype against, not a production dependency, until Deno publishes a stability statement.

Sources