Cells/Overview

Cells — Overview

A Cell is the fundamental unit of computation on tissue.systems. It is an isolated function that handles HTTP requests and returns HTTP responses.


The interface

Every Cell exports a default object with a fetch method:

export default {
  async fetch(request, env, ctx) {
    return new Response("ok");
  },
};
Argument Type Description
request Request The incoming HTTP request
env object Bound resources — databases, buckets, text values
ctx object Execution context — ctx.waitUntil(promise) lets work finish after the response is sent

The return value must be a Response (or a Promise<Response>).


Isolation

Each Cell runs in its own isolated V8 instance — a separate JavaScript runtime with its own memory, heap, and execution context. Cells cannot share memory with each other. There is no global state between requests or between Cells.

This isolation is by design. It means:

  • A bug in one Cell cannot affect another
  • Each Cell starts from a clean slate
  • Cells are horizontally scalable by nature

The isolate is reused across requests for warm performance. Redeploying the Cell immediately provisions a fresh isolate for subsequent requests.


What a Cell can do

  • Handle any HTTP method: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS
  • Parse and inspect request headers, URL, and body
  • Return any HTTP response: HTML, JSON, binary, redirects
  • Call external HTTP APIs using the standard fetch() function
  • Read and write c3 SQLite databases via the env.DB binding
  • Read and write g7 object storage via the env.BUCKET binding
  • Serve static file trees via the env.FILES binding
  • Run on a cron schedule via pulse — declared in ribo.toml

What a Cell cannot do

  • Access the local filesystem
  • Spawn processes or threads
  • Open TCP/UDP sockets directly (only fetch() is available)
  • Maintain state between requests without a binding
  • Communicate directly with other Cells

Cell kinds

Cells come in two kinds:

JavaScript — the most common kind. You write a .js (or bundled TypeScript) module and point ribo.toml at it. The module runs as-is in the V8 runtime.

WebAssembly (WASM) — a compiled binary, typically from Rust via wasm-pack. Useful for CPU-intensive work, existing Rust libraries, or code that must not be distributed as source. The WASM binary receives requests as a JSON-serialised string and returns a JSON-serialised response.


Addresses and URLs

Each Cell gets a stable address — a 13-character alphanumeric ID assigned on first deploy. The same Cell keeps its address across every redeploy; it never changes.

The public URL is:

https://<cell-name>.<account-subdomain>.tissue.dev

where <account-subdomain> is a stable per-account subdomain (e.g. strand-9c). For example, a Cell named my-cell is reachable at https://my-cell.strand-9c.tissue.dev. The URL is printed after every ribo deploy.


See also