concept

Local-First Software

created 2026-05-25 distributed-systems · local-first · offline · crdt · sync

Local-First Software

An architectural pattern where the local device is the source of truth, the server is a sync coordinator (not an authority), and the network exists only to exchange state when it’s available. Partition mode isn’t a degraded state — it’s the normal mode of operation.

The inversion

Most apps treat the server as canonical:

read/write → network → server → network → response
                       (critical path)

When the network is slow, the app is slow. When the network is gone, the app is broken.

Local-first flips this:

read/write → local DB (instant)

            sync layer (background, when network available)

            other devices / server replica

Every read and write hits a local database. No round trip. No spinner. Not fast — instant.

Why the architecture works

  • The app works completely offline because there’s no difference between offline and “normal.”
  • When devices reconnect, crdt|CRDT-based sync handles the diverged state in the background.
  • Recovery becomes routine infrastructure, not an incident.

The sync protocol that handles diverged state when devices reconnect is exactly the partition-recovery problem cap-theorem|Brewer's 2012 CAP paper described — but now solved by purpose-built tools rather than ad-hoc retry logic.

Tooling

  • yjs — collaborative-editing-centric CRDT, dominant for rich-text and editor use cases
  • automerge — JSON-document CRDT, shipped to millions in GoodNotes
  • Purpose-built sync engines — Replicache, Triplit, Jazz, PowerSync, Electric SQL — built specifically to make local-first practical for SaaS

Real apps you’ve used

  • A notes app that works at 35,000 feet (Bear, Apple Notes, Linear’s offline behavior).
  • Linear — issues are available when the WiFi drops; everything syncs when you land.
  • Figma (canvas) — partially local-first; CRDT-influenced for conflict resolution. See crdt.

That “feels fast” UX is partition recovery built into the architecture from the start, not a pleasant UX feature retrofitted on top of REST.

When to pick it

  • Apps where users expect “instant” — notes, todos, design tools, code editors.
  • Apps where offline use is real (mobile, travel, conferences, hospitals, fieldwork).
  • Apps where collaboration is multi-device for the same user (not just multi-user).

When not to pick it

  • Anything with strong global invariants — “balance never goes negative,” “username is unique,” “inventory count is accurate.” These need saga-pattern|sagas or coordinator-mediated writes; local-first doesn’t help.
  • High-write-rate analytics/event streams — local-first’s value is interactive responsiveness, not throughput.

See also