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.
At a glance
Section titled “At a glance”| 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. |
The one-sentence differentiator
Section titled “The one-sentence differentiator”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.