# jodit-collaboration

**jodit-collaboration adds real-time co-editing and in-editor comments to
the [Jodit](https://xdsoft.net/jodit/) rich-text editor.** To run it you
need three things: the **server** (a single Docker container, or a
Node.js ≥ 20 process), **PostgreSQL** if you want documents to survive
restarts, and the **`@jodit/collab-plugin` plugin** in your existing Jodit editor
pointed at the server's WebSocket endpoint. Multiple users then edit the
same document live, with named cursors, comment threads, crash-safe
persistence and full history replay. It is a
[**commercial product**](licensing.md): free to evaluate in demo mode
(`docker compose up`), licensed for production use.

Under the hood it is an **authoritative patch sequencer over WebSocket**
with pluggable authentication and storage. Every document change made in
the editor travels as a small, serializable, **id-addressed patch**, never
HTML. The server accepts patch batches from clients, transforms them
against concurrent edits (OT), assigns each batch a monotonic sequence
number, persists it to an append-only log, and broadcasts it to every
participant. All clients converge on the same document, verified by
property-based tests.

Alongside document sync, **comments are a first-class protocol feature**:
threads anchor to document text (the anchor travels through the same OT as
any other formatting), replies/resolve/edit are synchronized live,
authorship is server-assigned, and ownership rules are enforced
server-side. See [Comments in the protocol spec](protocol.md#comments).
The plugin ships an in-editor comments panel (Google-Docs style: cards
stick next to their anchors, orphaned threads keep their quoted text).

The project ships in npm packages plus a Docker image (install via npm; see
[Getting started](getting-started.md)). All parts are distributed under a
single [commercial license](licensing.md):

| Package                  | What it is                                                                                                                                                                                              |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `@jodit/collab-protocol` | The wire protocol **and the spec**: patch types, zod message schemas, the OT transform, reference `DocumentSession`/`ClientSync`, the auth/identity contract. Pure TypeScript: no DOM, no Jodit, no IO. |
| `@jodit/collab-plugin`   | The Jodit editor plugin: DOM capture → patches, remote cursors, the in-editor comments panel, and `CollabClient`.                                                                                       |
| `@jodit/collab-server`   | The server: Express + `ws`, room manager, pluggable auth hooks, memory/Postgres storage, history API, static demo hosting.                                                                              |

The editor side lives in the `@jodit/collab-plugin` plugin: it captures real DOM mutations from an
unmodified Jodit instance, normalizes them into patches, syncs them through
this server via `CollabClient`, and renders remote cursors and the
comments panel.

## Architecture

```text
Browser A                                Browser B
  Jodit editor                             Jodit editor
      |                                        |
      v                                        v
  @jodit/collab-plugin                     @jodit/collab-plugin
  (capture -> patches)                     (capture -> patches)
      |                                        |
      v                                        v
  CollabClient                             CollabClient
  (ClientSync rebase)                      (ClientSync rebase)
      |                                        |
      +------------- WebSocket ----------------+
                    (/collab/ws)
                          |
                          v
  ================ @jodit/collab-server ================
    WS handshake (hello -> welcome)
        |                        |
        v                        v
    Auth hooks              RoomManager
    (checkAuthentication         |
     / authorize)                v
                            Room (one per docId)
                            DocumentSession sequencer
                                 |
                                 v
                            CollabStorage (memory / postgres)
                                 ^
                                 |
    REST (/collab/health, /collab/docs/:id/history)
  ======================================================
```

Key design decisions:

- **Server-sequenced OT.** The server is the single source of canonical
  order. Clients submit optimistic batches with a `baseSeq`; the server
  rebases them against everything the author had not seen and broadcasts the
  result to everyone, including the author, who treats it as the ack
  (classic Jupiter model).
- **Id-addressed patches.** Nodes are addressed by stable ids, never by
  paths, so concurrent structural edits commute. The only index in the whole
  format is the character offset inside a single text node, handled by
  classic character-level OT.
- **Identity is always server-assigned.** The client sends a token, nothing
  else. Names, colors and roles come back from the server; the strict message
  schemas make a client-sent `name` a validation error, not a suggestion.
- **Append-only log + snapshots.** Every sequenced entry is persisted before
  it is broadcast; periodic snapshots keep recovery and history replay cheap.
- **Everything is pluggable.** Auth (`checkAuthentication`/`authorize`
  hooks), storage (`CollabStorage` adapter), the initial document, snapshot
  cadence.

## Documentation

- [Getting started](getting-started.md): Docker Compose in 5 minutes, npm
  usage, connecting the editor plugin.
- [On-premise installation](on-premise.md): the customer install guide
  covering the image, Compose, JWT auth, verification, upgrades, backup,
  sizing.
- [Protocol](protocol.md): **the spec**. Every message (including
  [comments](protocol.md#comments)), the sequencing algorithm, the
  transform rules, convergence. Enough to implement your own server or
  client.
- [Authentication](authentication.md): the identity contract, roles,
  per-operation authorization, JWT example, anonymous/demo mode.
- [Security](security.md): the content firewall, rate limiting,
  fail-closed defaults, memory bounds. What a security review will ask.
- [Storage](storage.md): the `CollabStorage` contract, memory and Postgres
  adapters, writing your own.
- [History & replay](history.md): the `GET /collab/docs/:id/history` API and
  the `…/html` server-side export.
- [Data lifecycle & privacy](data-lifecycle.md): what is stored, for how
  long, and how to erase it.
- [Webhooks](webhooks.md): POST document/comment/session events to your
  backend.
- [Configuration](configuration.md): every option and environment variable.
- [Deployment](deployment.md): Docker, Compose with Postgres, nginx,
  health checks, scaling notes.
- [Connection troubleshooting](connection-troubleshooting.md): symptoms
  mapped to causes, keyed to the server's error codes.
- [Licensing & purchasing](licensing.md): the cloud and on-premise
  editions, what is included, trial mode, how to buy.
