advanced 1 min answer

Design client state for a document application supporting offline editing, real-time collaboration and instant navigation.

client-stateofflinesynccachingnotion
Show the full answer Hide the answer

Separate the categories

The most common mistake is one state container holding everything. These have different lifetimes, different persistence needs and different failure behaviour:

  • Document state — the content being edited. Persisted locally, synchronised, conflict-resolvable.
  • Server cache — data fetched from the API. Has a freshness policy, is invalidated, is not authored by the user and is always recoverable by refetching.
  • UI state — panels open, cursor position, scroll. Ephemeral, local, never synchronised.
  • Session state — identity, permissions, workspace. Fetched at start, refreshed on change.

Conflating document state with server cache is what makes offline support and cache invalidation fight each other: you cannot discard a stale cache entry that also contains the user's unsaved edits.

Offline editing

  • Local persistence as the source of truth while offline, with a durable client-side store rather than memory.
  • A queue of pending operations, applied optimistically, retried on reconnection.
  • A conflict resolution strategy chosen for the data shape — CRDTs for text, last-write-wins for independent fields, explicit user resolution for genuinely conflicting intent.
  • Clear communication of sync state. Users tolerate offline editing; they do not tolerate uncertainty about whether their work is saved. The status indicator is a core feature, not an affordance.

Instant navigation

Prefetch on intent — hover, viewport proximity — and render from cache immediately with revalidation behind it. The perceived speed comes from showing something correct instantly, not from fetching faster.

The hardest part

Reconciling an optimistic local change with a server response that differs. Rolling back a change the user already saw is jarring, and applying both produces duplicates. This needs a deliberate policy per operation type, and it is where most of the real defects in this architecture live.