Engineering

Conflict-Free Sync: Resolving Local Offline Edits with Yjs and CRDTs

In a local-first application, the network is treated as a transient utility, not an absolute constraint. Users must be able to edit notes, adjust workspace structures, and trigger commands in train tunnels, flights, or café spots with flaky Wi-Fi. Resolving these overlapping multi-device edits without a centralized database coordinator meant using Yjs and CRDTs.

"Data conflicts shouldn't be resolved by server-side locks. Math provides a deterministic, zero-trust way to merge updates."

CRDTs (Conflict-free Replicated Data Types) allow two clients to modify their local state independently and merge changes automatically, arriving at the exact same state without requiring a cloud coordinator. Maple embeds Yjs arrays inside our SQLite index files to guarantee instant offline edits.

Sync State Merging

Figure 2: Local CRDT State Vector Sync
Client A Update Yjs State Vector Deterministic Merge Unified State

Merge Framework Benchmarks

Attribute Centralized Lock Sync Local-First CRDT (Yjs)
Offline edit block Yes (Fails without internet) No (Frictionless offline)
Merge Conflict rate Frequent (Overwrite warnings) 0% (Mathematically resolved)
Merge Overhead time Variable (Requires API check) < 1 ms (Local assembly)

Yjs Transaction Schema Example

import * as Y from 'yjs';

// Initialize local Yjs document
const ydoc = new Y.Doc();
const ymap = ydoc.getMap('workspace_config');

// Capture transaction safely locally
ydoc.transact(() => {
  ymap.set('routines_v1', 'active_summary');
  ymap.set('last_modified', new Date().toISOString());
});

// Encode update chunk for SQLite storage
const updateBytes = Y.encodeStateAsUpdate(ydoc);