Skip to main content

Collaborative notes

This guide walks through a practical collaborative notes pattern using NodalMerge. You will implement:
  • Shared note content with text CRDT semantics
  • Metadata and list/index state with map/list primitives
  • Presence-driven collaboration signals (cursors, active users)
  • Local-first writes with eventual canonical refinement

Data model

Use separate namespaces by concern:
  • notes/<noteId>/content for text body
  • notes/<noteId>/meta/* for title/tags/author metadata
  • notes/index (list or map) for ordering and note references
  • presence payloads for ephemeral cursor/selection state
Keep note content durable in room state. Keep ephemeral editing signals in presence only.

Step 1: connect the room

Step 2: model note content and metadata

Use text APIs for editable body content and map-style keys for note metadata.

Step 3: wire UI updates

Subscribe to runtime or note-specific signals and re-read current note projection for rendering. Pattern:
  1. Event arrives
  2. Read current text + metadata keys
  3. Re-render note UI
Avoid mutating UI state from assumptions about event ordering.

Step 4: add presence

Render remote collaborator cursors from presence peer snapshots. Presence should disappear naturally on disconnect/staleness.

Step 5: support offline editing

Enable local persistence and treat edits as optimistic:
  • Apply edits immediately
  • Push when connected
  • Reconcile canonical updates after reconnect
Do offline/reopen drills to validate note durability and convergence behavior.

Suggested UX states

Use explicit editor states:
  • connected
  • reconnecting
  • offline-local
  • syncing
  • conflict-or-rejection-visible
Clear UX states reduce user confusion during network churn.

Common pitfalls

  • Storing note content in presence
  • Using map writes for rich editable text
  • Ignoring reconnect state transitions in editor UI
  • Not separating note metadata and body keys

Verification checklist

  • Two clients edit same note concurrently and converge
  • Offline edit then reconnect merges as expected
  • Presence appears/disappears correctly per peer lifecycle
  • Metadata updates do not corrupt text content rendering