> For the complete documentation index, see [llms.txt](https://docs.rowsncolumns.app/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rowsncolumns.app/collaboration/real-time-collaboration.md).

# Real time collaboration

With a supported real-time back-end, you can have a full collaborative and real-time Spreadsheet. The UI is data agnostic, so both OT and CRDT data structures are supported.

SheetGrid exposes the following prop to highlight users in the canvas grid.

```tsx
const App = () => {
  const currentUserId = 1
  <SheetGrid
    users={
      [
        {
          userId: 1,
          title: 'Foo bar',
          // Active cell that will be highlighted
          activeCell: { rowIndex: 2, columnIndex: 3},
          // Which sheetID is currently in focus
          sheetId: 1
        },
        {
          userId: 2,
          title: 'Foo bar',
          activeCell: { rowIndex: 2, columnIndex: 3},
          sheetId: 1
        }
      ]
    }
    userId={currentUserId}
  />
}
```

## Immer and useSpreadsheetState

If you are using `useSpreadsheetState` hook to manage the state of Spreadsheet, Immer is the state library that is used to modify state.

Immer has really good API for JSON patches that is sent over the wire for real-time collaboration. JSON patches also helps in building a robust undo/redo functionality.

`onChangeHistory` callback is fired when user modifies state.

```tsx
import { SpreadsheetProvider, CanvasGrid } from "@rowsncolumns/spreadsheet";
import { tokenize as tokenizer } from "@rowsncolumns/calculator";
import { useSpreadsheetState } from "@rowsncolumns/spreadsheet-state";

const MySpreadsheet = () => {
  const {} = useSpreadsheetState({
    onChangeHistory(patches) {
      // Send this over the wire to Yjs, Pusher, Liveblocks etc
      console.log(patches);
    },
  });
  return (
    <CanvasGrid
      rowCount={1000}
      columnCount={1000}
      sheetId={1}
      tokenizer={tokenizer}
      users={[{ ... }]}
      userId={}
    />
  );
};

const App = () => (
  <SpreadsheetProvider>
    <MySpreadsheet />
  </SpreadsheetProvider>
);
```
