Architecture
The synctable runtime has six layers, each owned by one package. Data flows bottom-up through the database engine, out through the sync protocol, and into the local-first client.
System diagram
Browser (React hooks, Dexie+Zustand)
| hint-then-fetch
Hono Server (/sync, /hints, /trace, /commit)
| coalesced hints, fetch_since, SSE
@synctable/server (admin stream, 7-hop trace, OTel)
| outbox drain
@synctable/core (Postgres: catalog, capture, applier, DAG, outbox, NOTIFY)Components
| Package | Role |
|---|---|
| @synctable/core | Authoring API, codegen, reverse projection, Drizzle plugin |
| @synctable/server | Hono router factory, sync protocol, subscriber, OTel |
| @synctable/client | Dexie persistence, Zustand store, command queue, reconcile worker |
Design decisions
- Target is a table, not a native MATERIALIZED VIEW — tables can be triggered, replicated, and partially updated.
- Change gate at capture time — unwatched columns never enqueue the view.
- Two delivery paths: NOTIFY (in-cluster doorbell) + outbox (durable, ordered cursor).
- Auth-scope column in every key — deltas cannot cross tenant boundaries.