Real-time Collaborative Spreadsheet Editing in Mobile Applications
Spreadsheet differs from text. It has structure: rows, columns, cells, formulas, dependencies between cells. Synchronization algorithms working for text documents (Y.js YText, CRDT for sequences) apply differently here. Concurrent change of cell B3 and simultaneous formula change =SUM(B1:B5) in C1 — two independent events with data dependency.
Data Model: Not Array of Rows, But Map of Cells
Spreadsheet in CRDT representation — Y.Map (or analog), where key is "row:col" string, value is cell object. Y.js YMap supports concurrent operations at individual key level: two users edit different cells simultaneously — no conflict. Two edit one cell — last write wins (Last-Write-Wins semantics).
const ycells = ydoc.getMap('cells');
ycells.set('3:2', { value: '=SUM(A1:A3)', formatted: '15', style: { bold: true } });
ycells.observe(event => {
event.changes.keys.forEach((change, key) => {
if (change.action === 'update' || change.action === 'add') {
const [row, col] = key.split(':').map(Number);
recalculateAffectedFormulas(row, col);
rerenderCell(row, col);
}
});
});
Last-Write-Wins for cells — acceptable in most scenarios. For critical data (financial spreadsheets) need conflict detector and UI for manual resolve.
Adding and Removing Rows/Columns: Structural Changes
More complex than cell change. Inserting row before row 5 should shift all formula references: =B5 becomes =B6. Concurrent row insertion by two users — insertion order affects final structure.
Y.js YArray for row list with YMap for each row — classic scheme. On YArray insert, CRDT guarantees deterministic merge order (based on clientId and clock). Formulas after structural changes need recalculation via dependency graph.
Formula recalculation — separate topic. HyperFormula (hyperformula.js) — open-source formula engine (Excel analog), works in JavaScript. Supports 400+ functions. Integrates with Y.js: when receiving CRDT update apply it to HyperFormula via setSheetContent() and get recalculated values.
Mobile Spreadsheet Rendering
FlashList (React Native) with 2D scrolling — non-standard case. Standard FlatList / ScrollView not optimized for large spreadsheets with frozen headers and cell virtualization.
Solutions:
-
react-native-table-component— simple, no virtualization, not for large spreadsheets. -
react-native-spreadsheet— exists but outdated. - Custom renderer via
react-native-gesture-handler+react-native-reanimated— full control, virtualization manually.
Native Android: RecyclerView with GridLayoutManager, virtualization built-in. iOS: UICollectionView with UICollectionViewCompositionalLayout for 2D scrolling with flexible cell sizes.
Custom cell editor: TextInput with formula support (starts with = — switch mode). On iOS autocorrect breaks formulas (=SUM becomes =Sum or underlined). Need autocorrectionType = .no and spellCheckingType = .no for formula cells.
Range Selection: B2:D5
When entering formula user should click cell and drag for range selection — classic Excel UX. On mobile: custom gesture recognizer over spreadsheet tracking pan gesture computing cell range by coordinates. Need hitTest to determine cell by touch point.
Multiple users simultaneously selecting ranges — show via Awareness Protocol (like cursors in text editor), but color-coded by user.
Sync via WebSocket: Optimistic Update
Local cell change applies to UI immediately (optimistic update). Parallel Y.js encodes operation to update binary and sends to server. Server broadcasts update to other clients. If conflicting update arrives — Y.js merge applies, UI redraws.
For large spreadsheets (1000+ rows) important not to redraw entire spreadsheet on each remote update. Track event.changes.keys in observer and redraw only changed cells + dependent formulas.
Assessment
MVP with Y.js + HyperFormula on React Native (up to 100 rows, basic formulas, 2–3 concurrent users) — 10–16 weeks. Full-fledged Google Sheets-like mobile editor with thousands of rows, complex formulas and structural changes — 6–12 months.







