Skip to content

Where datadata sits

The local-first community has converged on a fairly standard set of dimensions for describing sync engines (as popularized by the Local-First Landscape). Here is datadata, answered along those lines.

Dimension datadata
Maturity Early-stage / pre-alpha. Working, actively reshaped, not open source yet.
Distribution TypeScript library (client + server), self-hosted. No hosted service.
Data model Documents — typed JSON with embedded Yjs text. Schemas are documents too.
Schema management Schema documents (optionally authored in TypeScript — typed, no codegen — and upserted at startup) with append-only migrations; documents migrate on next read with write-back; invalid documents flagged, not dropped; dynamic runtime schemas.
Authority Centralized — one server per folder orders all events.
What syncs up JSON Patches (optionally guarded) + Yjs updates.
What syncs down Initial snapshot, then patches + Yjs updates; reconnects catch the CRDT lane up with exact state-vector diffs.
Replication granularity Per-document subscriptions within a folder; no partial replication inside a document, no cross-folder sync.
Data size Documents (and single events) cap at 1.9 MB in the current backend; model larger data as more documents.
Conflict handling Layered: server ordering + opt-in guards for structure; Yjs CRDT for rich text; three-way staged previews in sessions.
Optimistic updates Yes — core mechanism, with clean rejection.
Offline reads Whatever the client holds in memory; with the opt-in persistence adapter, a persisted document cache renders cached documents on an offline boot (offline-cached sync status) with pending writes re-projected on top. Schemas and the index are pinned, so validation works offline too.
Offline writes Writes made while disconnected replay on reconnect (structured writes last-writer-wins; locally held Yjs content merges back); an opt-in IndexedDB write queue makes the buffer durable across a page reload — a reload becomes a reconnect, under the same de-dup/horizon rules.
Local query Document reads + subscriptions — no query language, no cross-document select/project. An experimental projection layer reshapes a (fully synced) document into ergonomic views; writable lenses are alpha. For queries, the supported pattern is a derived store: project changes into another document or database and query that.
Server persistence SQLite (Durable Object storage) via pluggable adapter; snapshots + append-only event logs (no compaction).
Transport WebSockets; in-process bus for server-side agents, tests, demos.
Auth Token at the door (minted by host app), then engine-enforced authorization inside the folder: declarative role rules per docType, whole-document read filtering, scope caps for agents, app policy callbacks for per-document rules — and capability-aware clients that predict verdicts locally.
Encryption Transport-level only. No E2E encryption — incompatible with server-side validation as designed.
Rich text Embedded Yjs documents; ephemeral presence documents (sys:presence:<presenceType>:<docId>, schema-validated) with a y-protocols awareness bridge over a cell’s sys:awareness field for editor cursors — in live documents and in staged sessions.
Client platforms Browser + server-side JS. React (Jotai) bindings; devtools panel.
AI agents A design focus: sessions, attribution, in-process clients, agent-writable schemas.

Everything — user data, schemas, the engine’s own state, staged work — is a document behind one small referential API, with an explicit staging layer (sessions) designed for humans and AI agents proposing changes to shared data.

If those dimensions read like a fit, continue to Design decisions; if some of the “No”s above are deal-breakers, When to use it names better-suited engines without hard feelings.