Skip to main content
Real-time collaboration is currently in development. The underlying infrastructure is implemented, but the feature is not yet fully available.

Overview

Ganimede uses Yjs, a high-performance CRDT (Conflict-free Replicated Data Type) library, to enable real-time collaborative editing of notebooks. Multiple users can work on the same notebook simultaneously without conflicts.

Architecture

Ganimede’s collaboration system is built on a robust WebSocket-based architecture:

WebSocket Server

The collaboration server is implemented using ypy-websocket and runs on port 1234:
from ypy_websocket import ASGIServer, WebsocketServer, WebsocketProvider
import y_py as Y

# Initialize Yjs document
ydoc = Y.YDoc()

# WebSocket server for collaboration
async def server_task():
    async with (
        WebsocketServer(log=log) as websocket_server,
        serve(websocket_server.serve, "localhost", 1234, close_timeout=1),
    ):
        await asyncio.Future()  # run forever
From api/ganimede/main.py:38-43

WebSocket Provider

Clients connect to the collaboration room via WebSocket:
# Connect to collaboration room
websocket = await connect("ws://localhost:1234/g-y-room")
websocket_provider = WebsocketProvider(ydoc, websocket, log=log)
task = asyncio.create_task(websocket_provider.start())
await websocket_provider.started.wait()
From api/ganimede/main.py:58-61

Shared Data Structures

The Yjs document synchronizes multiple data structures across all connected clients:

Notebook Elements

  • Cells Array (ydoc.get_array("cells")): The list of cell IDs in the notebook
  • Cell Maps: Each cell is stored as a shared map with properties:
    • id: Unique cell identifier
    • type: Cell type (code, markdown)
    • source: Cell content as Y.YText (collaborative text editing)
    • execution_count: Number of times the cell has been executed
    • outputs: Cell execution outputs as Y.YArray
    • top, left, width, height: Canvas positioning
    • collapsed: Collapse state
    • state: Execution state (idle, running, queued, done)

Graph Structures

  • np_graph (ydoc.get_map("np_graph")): Next-previous directed graph for cell flow
  • pc_graph (ydoc.get_map("pc_graph")): Parent-children directed graph for hierarchical structure

Other Shared State

  • run_queue (ydoc.get_array("run_queue")): Queue of cells waiting to execute
  • nb_path (ydoc.get_text("nb_path")): Path to the notebook file

Frontend Integration

The frontend uses Yjs bindings for real-time synchronization:

Dependencies

From ui/package.json:
{
  "dependencies": {
    "yjs": "^13.6.7",
    "y-websocket": "^1.5.0",
    "y-monaco": "^0.1.4",
    "y-prosemirror": "^1.2.1",
    "y-protocols": "^1.0.5"
  }
}

Editor Bindings

  • y-monaco: Collaborative editing for code cells (Monaco editor)
  • y-prosemirror: Collaborative editing for markdown cells

How It Works

  1. Document Initialization: When a notebook is opened, the Yjs document is initialized with the notebook’s content
  2. WebSocket Connection: The client connects to the collaboration server at ws://localhost:1234/g-y-room
  3. Synchronization: Yjs automatically synchronizes all changes between connected clients using efficient delta updates
  4. Conflict Resolution: CRDTs ensure that concurrent edits are merged without conflicts
  5. Persistent State: Changes are saved to the notebook file via the checkpoint system

Benefits of CRDT-Based Collaboration

No Conflicts

CRDTs mathematically guarantee that all users see the same final state

Offline Support

Continue working offline and sync when reconnected

Low Latency

Changes appear instantly without server round-trips

Scalable

Yjs efficiently handles large documents and many users

Current Status

From the Ganimede roadmap:
  • Infrastructure: ✅ Implemented (Yjs, WebSocket server, data structures)
  • Feature: ⏳ In development (RTC Demo from Sep 23)
The collaboration infrastructure is fully implemented in the codebase. The feature is being refined for production readiness.

Try It Out (When Available)

Once collaboration is enabled, multiple users will be able to:
  • Edit cells simultaneously with cursor awareness
  • See real-time updates to cell outputs
  • Move and resize cells on the canvas together
  • Queue and run cells collaboratively
  • Work on different parts of the notebook without conflicts
The combination of Yjs CRDT and Ganimede’s 2D canvas will enable unique collaborative workflows not possible in traditional notebooks.

Build docs developers (and LLMs) love