Menu
docs

Architecture

How requests, identity, tenant data, and asynchronous work fit together.

Request and data boundaries

React Router loaders and actions run directly in workerd. They call authorization-aware services without self-fetching, while TanStack Query owns browser caching and invalidation.

Better Auth owns its canonical identity tables. Application projections, tenant records, audit events, and the transactional outbox live in D1. Public and private media use separate R2 buckets.

Asynchronous work

Every provider call starts as a versioned outbox record. The jobs Worker leases eligible rows, performs the side effect with a stable idempotency key, records a receipt, and then completes the row.

type JobEnvelope = {
  version: 1;
  id: string;
  type: JobType;
  entityId: string;
  idempotencyKey: string;
};

Realtime

Durable Objects broadcast short-lived invalidation hints. Messages contain identifiers, not authoritative rows or secrets. Clients refetch through the normal authorized API.

Runtime compatibility

Runtime modules use Web APIs such as fetch, Request, Response, crypto.subtle, and streams. Node APIs are restricted to build and test tooling.