ShareDB (OT) Collaboration

Real-time collaboration using ShareDB

ShareDB is an OT-based real-time database that enables collaborative editing with automatic conflict resolution. The @rowsncolumns/sharedb package provides a React hook for integrating ShareDB with your spreadsheet.

Installation

yarn add "@rowsncolumns/sharedb sharedb reconnecting-websocket"

Quick Start

import { useShareDBSpreadsheet } from "@rowsncolumns/sharedb";
import ShareDBClient from "sharedb/lib/client";
import ReconnectingWebSocket from "reconnecting-websocket";

// Create ShareDB connection
const socket = new ReconnectingWebSocket("ws://localhost:8080");
const connection = new ShareDBClient.Connection(socket);

function SpreadsheetEditor() {
  const [sheetData, setSheetData] = useState({});
  const [sheets, setSheets] = useState([]);
  const [tables, setTables] = useState([]);
  const [sheetId, setSheetId] = useState(1);
  const [activeCell, setActiveCell] = useState({ rowIndex: 1, columnIndex: 1 });

  const { onBroadcastPatch, users, synced, isLeader } = useShareDBSpreadsheet({
    connection,
    collection: "spreadsheets",
    documentId: "my-spreadsheet",
    userId: "user-123",
    title: "John Doe",
    sheetId,
    activeCell,
    initialSheets: [],
    onChangeSheetData: setSheetData,
    onChangeSheets: setSheets,
    onChangeTables: setTables,
    onChangeActiveSheet: setSheetId,
    calculateNow,
    enqueueGraphOperation: (op) => {
      // Handle dependency graph updates for formula recalculation
    },
  });

  // Pass onBroadcastPatch to useSpreadsheetState
  return <Spreadsheet sheetData={sheetData} sheets={sheets} users={users} />;
}

Integration with useSpreadsheetState

Connect the ShareDB adapter to your spreadsheet state:

Setting Up a ShareDB Server

Basic Server

Create a file server.js:

Install dependencies:

Run the server:

Server with MongoDB Persistence

For production environments, persist data to MongoDB:

Server with PostgreSQL Persistence

Document Structure

The ShareDB document stores all spreadsheet data:

Cell Key Format

Cell keys follow the pattern ${sheetId}!${A1Address}:

Key
Description

"1!A1"

Cell A1 on sheet 1

"2!B5"

Cell B5 on sheet 2

"1!AA100"

Cell AA100 on sheet 1

CellDataV3 Structure

Each cell value is stored with its position metadata:

Presence Awareness

The hook automatically manages presence, allowing you to display other users' cursor positions:

Each user in the users array includes:

Leader Election

The adapter automatically elects a leader among connected clients. The leader is responsible for coordinating recalculation operations.

Error Handling

Handle connection errors with the onError callback:

Why ShareDB for Spreadsheets?

ShareDB's Operational Transformation (OT)arrow-up-right approach is particularly well-suited for spreadsheet collaboration compared to CRDT-based solutions like Yjs.

Comparison with Y.js

Aspect
ShareDB (OT)
Yjs (CRDT)

Conflict Resolution

OT - Server determines canonical order

CRDT - Automatic merge, eventual consistency

Server Required

Yes

Optional (P2P possible)

Recalculation

Leader election makes coordination easy

Requires additional coordination layer

Undo/Redo

Manual (via Immer patches)

Built-in

Offline Support

Requires server connection

Full offline-first support

Audit Trails

Sequential operation log

Distributed history

Data Persistence

MongoDB, PostgreSQL, etc.

LevelDB, IndexedDB, etc.

Why OT Works Well for Spreadsheets

  1. Cell-level granularity - The V3 flat map structure ("sheetId!A1" keys) maps perfectly to ShareDB's json0 OT type. Each cell is an independent key-value pair, so conflicts are rare.

  2. Server-centric calculation - Spreadsheets typically need a server anyway for formula calculation, persistence, and permissions. OT's server authority aligns naturally with this architecture.

  3. Simpler undo/redo - OT's sequential operation log makes history management straightforward. The server maintains a clear order of operations.

  4. Predictable conflict resolution - When two users edit the same cell simultaneously (rare in practice), the server determines the winner. No surprising merged states.

  5. Batched operations - Large operations (paste 1000 cells, delete rows) can be batched into a single atomic submitOp call, maintaining consistency.

When to Choose ShareDB

  • Need a traditional client-server architecture

  • Want to leverage existing MongoDB/PostgreSQL infrastructure

  • Prefer predictable OT semantics for conflict resolution

  • Server-side formula calculation is required

  • Need clean audit trails and operation history

When to Choose Y.js

  • Need offline-first capabilities

  • Want peer-to-peer collaboration without a server

  • Need built-in undo/redo support

  • Decentralized architecture is preferred

For most spreadsheet use cases with a server backend, ShareDB provides a cleaner, more predictable collaboration model.

Last updated