Real-time Collaborative Document Editing in Mobile Applications
Real-time collaborative text editing is one of technically complex tasks in mobile development. Not because algorithms themselves are complex, but because mobile environment adds several dimensions: unstable network, background mode, native keyboard with composition events, users with 300ms+ latency due to poor signal.
Choosing Synchronization Algorithm
Two practical approaches: Operational Transform (OT) and CRDT (Conflict-free Replicated Data Type).
OT — proven in Google Docs, Apache Wave. Operations (insert/delete with position) transform on server accounting for concurrent changes. Server is coordinator, all operations go through it. Advantage: single operation history, no conflicts by definition. Disadvantage: server mandatory, offline work requires buffering with subsequent merge.
CRDT — algorithms like Automerge, Y.js, RGA (Replicated Growable Array). No central coordinator, merge works locally. Ideal for offline-first scenarios where user edits document without network and syncs later. Y.js — de facto standard for web and React Native.
For mobile corporate editor (Google Docs-like) — OT via WebSocket with coordinator server. For collaborative notebook with offline mode — Y.js + WebRTC or Y.js + WebSocket with sync provider.
Y.js in React Native: Real Integration
yjs — pure JavaScript, works in React Native without modifications. y-websocket — sync provider via WebSocket. Typical setup:
import * as Y from 'yjs';
import { WebsocketProvider } from 'y-websocket';
const ydoc = new Y.Doc();
const provider = new WebsocketProvider('wss://your-server.com/sync', 'doc-room-id', ydoc);
const ytext = ydoc.getText('document');
YText — CRDT type for text with formatting support (bold, italic, headers). Integrates with Quill.js, ProseMirror, Slate.js on web. In React Native — via react-native-webview with Quill inside, or native text editor with manual Y.js sync.
Second option harder but gives native UX. Custom TextInput in React Native doesn't support beforeInput events — need NativeEventEmitter and native keyboard event interception. On iOS — UITextViewDelegate, on Android — InputFilter or TextWatcher.
Cursors and Awareness
Y.js Awareness Protocol — lightweight mechanism for ephemeral data (cursors, presence, text selection) distribution between participants. Not stored in document, doesn't affect CRDT history.
provider.awareness.setLocalState({
user: { name: 'Ivan', color: '#3B82F6' },
cursor: { anchor: 45, focus: 45 }
});
provider.awareness.on('change', () => {
const states = Array.from(provider.awareness.getStates().values());
// update other users' cursor positions
});
Displaying other cursors in native TextInput — non-trivial. Need to compute CGRect for cursor position via UITextView.caretRect(for:) on iOS and Layout.getDesiredWidth() / getLineTop() on Android. Position in chars → coordinates in pixels — different APIs per platform.
Formatting Conflicts and Resolution
Y.js YText formatting via Delta-like operations with attributes. Concurrent formatting (one user makes text bold, other simultaneously — italic on overlapping range) — CRDT resolves automatically: both attributes apply.
Harder with semantically incompatible operations: one user sets H1 on paragraph, other — H2 on same paragraph. Y.js picks one (by clientId), but UI should warn or provide manual resolve tool.
Persistence and History
Y.js document serialized to Uint8Array via Y.encodeStateAsUpdate(). For mobile persistence: store in SQLite via expo-sqlite or react-native-sqlite-storage. When opening document: load saved state, apply via Y.applyUpdate(), then connect to WebSocket and get diff from server.
Server should maintain y-leveldb or y-redis for document state storage. y-websocket server — minimalist Node.js from package, good for start. For production: persistence + auth + room access control.
Assessment
Collaborative document editor — complex task. MVP timeline (basic text + sync + cursors) on React Native: 8–14 weeks. Native iOS/Android with rich formatting — 16–24 weeks. Significant portion — native text editor, not network sync.







