What celld is
celld is a separate runtime. It embeds V8 and implements the Workers runtime API. It isn’t workerd, Node.js, or a browser. celld runs your App in the sandbox as a dev server, and in production after a deploy. Write standard web-platform JavaScript:fetch, Request, Response, streams, URL, and Web Crypto. Use the bindings that you declare in the wrangler.json file. A subset of Node.js built-in modules works without the nodejs_compat flag. For more information, see Runtime reference.
Unsupported products and features
celld doesn’t provide Vectorize, Hyperdrive, Browser Rendering, or Email Workers, so the entry module can’t export anemail handler. The following table lists the other unsupported features and what to do instead.
Behavior differences
The following differences are the ones that most often surprise developers who know Workers.The Cache API always misses
caches.default and caches.open exist, but every lookup misses and put stores nothing. The cache option of fetch isn’t available. To cache a value, store it in KV with an expirationTtl. For more information, see Web API differences.
KV is strongly consistent
On celld, one owner serves each KV namespace, so aget always returns the last put from every node. Cloudflare guidance about stale reads doesn’t apply. There’s no edge cache, and the cacheTtl option has no effect. KV still has no atomic increment and no compare-and-swap, so use a Durable Object or D1 for counters. For more information, see KV.
R2 has no presigned URLs, public buckets, or S3 API
Every upload and download goes through your Worker, which handles authorization and streams the body. To share a file, create a random token, store the token-to-key mapping in KV with an expiry, and serve the file from a Worker route. R2 event notifications,ssecKey, lifecycle rules, and jurisdiction aren’t available. For more information, see R2.
D1 has no read replicas, Time Travel, or SQL transactions
Every D1 query goes to the primary database, so each read sees all committed writes. ThewithSession() method always uses the primary. The dump() method throws, and there’s no Time Travel and no REST API. Application SQL can’t use BEGIN, COMMIT, ROLLBACK, or SAVEPOINT. To run statements in one transaction, use batch(). Judt applies migrations at deploy, and the dev server applies them to the dev database. For more information, see D1.
The request.cf object has no location data
The request.cf object has no geolocation and no colo data. celld also removes the Content-Length header from Worker responses, except for responses to HEAD requests. For more information, see Web API differences.
Clocks advance only at I/O
Date.now() and performance.now() move forward only when your code does I/O. A loop that only uses the CPU measures 0 ms. For more information, see Web API differences.
The wrangler.json file accepts few keys
The wrangler.json file accepts only name, main, no_bundle, compatibility_date, compatibility_flags, vars, and the binding keys that the feature pages document. Deploy refuses every other key, for example routes, env, observability, ai, and build. To run a build, add a build script to the package.json file. For more information, see Configure wrangler.json.
celld creates bindings on first use
You don’t provision D1 databases, KV namespaces, R2 buckets, or queues. celld creates each one the first time that your code uses it. A typo indatabase_name, a KV id, or bucket_name therefore gives you a new, empty store, and the old data stays under the old name. For more information, see Configure wrangler.json.