Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/denoland/celld/llms.txt

Use this file to discover all available pages before exploring further.

celld deploy packages a Wrangler project — your JavaScript bundle and any static assets — and writes the result to your fleet bucket. Every running node watches the bucket and loads the latest deployment automatically. You do not need to restart nodes or push to each machine individually.

Prerequisites

Asset-only projects (no main entry, only an assets directory) do not require esbuild. You can skip the esbuild installation step for those.
For projects that include Worker code, esbuild must be on your PATH before running celld deploy. The deploy command invokes esbuild internally to bundle your entry module into a single file. Install esbuild with npm or a standalone binary:
npm install -g esbuild
Verify it is available:
esbuild --version
You can also point celld deploy at a specific binary with the CELLD_ESBUILD environment variable:
export CELLD_ESBUILD=/usr/local/bin/esbuild

Deploy a project

Run celld deploy from the root of your Wrangler project directory, passing the same bucket settings you use to start a node:
celld deploy . \
  --bucket "$CELLD_BUCKET" \
  --endpoint "$S3_ENDPOINT" \
  --region "$AWS_REGION"
The first argument is the path to the project directory (. for the current directory). The three flags map to the same environment variables used by celld itself, so if those variables are already exported you can omit the flags:
export CELLD_BUCKET=s3://my-fleet-bucket
export S3_ENDPOINT=https://ACCOUNT_ID.r2.cloudflarestorage.com
export AWS_REGION=auto

celld deploy .
After a successful deploy, every live node picks up the new bundle from the bucket the next time it routes a request to that Worker — no restart required.

Supported wrangler.jsonc keys

celld deploy accepts wrangler.jsonc or wrangler.json. It does not accept wrangler.toml.
If your wrangler.jsonc contains any key that celld does not recognise, the deploy stops immediately with an error that names the offending key. Remove the key from the file or deploy that project with Wrangler instead of celld deploy.
The supported keys are:
KeyDescription
nameThe name of the Worker. Used as the application identifier inside the fleet.
mainPath to the Worker entry module. Required for projects that contain Worker code; can be omitted for asset-only projects.
compatibility_dateSets the Workers compatibility date, e.g. "2026-01-01". Controls which compatibility-gated behaviours are active.
compatibility_flagsArray of compatibility flag strings, e.g. ["js_rpc"]. celld honours the flags it models; unknown flags are accepted without effect.
durable_objectsObject with a bindings array. Each entry has name (the binding name in env) and class_name (the exported class).
migrationsArray of migration objects. Each object has a tag string and a new_sqlite_classes array listing class names that receive a SQLite storage namespace on first activation.
assetsObject that describes the static-asset directory. Sub-keys: directory (path on disk), binding (env name for the asset fetcher), html_handling (e.g. "auto-trailing-slash"), not_found_handling (e.g. "404-page"), run_worker_first (boolean — route every request through the Worker before serving an asset).
servicesArray of service-binding objects. Each entry has binding (env name) and service (the target Worker name).
varsObject of plain-text environment variables exposed to the Worker as env.*.

Example: counter application

The following wrangler.jsonc is from the bundled counter example. It registers a Durable Object class and adds a migration that provisions SQLite storage on first use:
{
  "name": "counter",
  "main": "index.js",
  "compatibility_date": "2026-01-01",
  "durable_objects": {
    "bindings": [{ "name": "COUNTER", "class_name": "Counter" }]
  },
  "migrations": [{ "tag": "v1", "new_sqlite_classes": ["Counter"] }]
}
And the Worker code that goes with it:
export class Counter {
  constructor(state, env) { this.state = state; }
  async fetch(request) {
    let n = (await this.state.storage.get("n")) ?? 0;
    n++;
    await this.state.storage.put("n", n);
    return new Response(JSON.stringify({ n, url: request.url }), { status: 200 });
  }
}

export default {
  async fetch(request, env) {
    const id = env.COUNTER.idFromName("room-42");
    return env.COUNTER.get(id).fetch(request);
  }
};
Deploy it:
cd examples/counter
celld deploy . \
  --bucket "$CELLD_BUCKET" \
  --endpoint "$S3_ENDPOINT" \
  --region "$AWS_REGION"

Unsupported keys

The following keys are explicitly not supported by celld deploy:
KeyReason
routesCloudflare platform routing; celld’s ingress is handled at the load-balancer or proxy layer.
kv_namespacesWorkers KV is a separate consistency model not provided by celld.
triggersCron triggers and other platform-level triggers are not available.
Any other unrecognised key also causes the deploy to fail. The error message names the key so you can locate and remove it quickly.
Unknown keys fail loudly at deploy time — they are never silently ignored. This is intentional: a silent compatibility gap would hide configuration mistakes. Check the error message for the exact key name, then either remove it or switch to deploying with Wrangler directly.

Build docs developers (and LLMs) love