# Getting started

Jodit Collaboration is a **server** plus a **Jodit editor plugin**: run the
server (a Docker container or a Node.js ≥ 20 process, with PostgreSQL for
persistence), add the `@jodit/collab-plugin` plugin to your editor, and your
users co-edit and comment on documents in real time. This page gets a demo
running in five minutes and shows the frontend wiring; for a production
customer install see [On-premise installation](on-premise.md).

Everything ships as public artifacts:

| Artifact                     | Where                                       |
| ---------------------------- | ------------------------------------------- |
| `@jodit/collab-plugin`       | npm: the editor plugin (browser)            |
| `@jodit/collab-server`       | npm: the sequencer server (Node.js)         |
| `@jodit/collab-protocol`     | npm: the wire protocol / OT (shared)        |
| `xdsoft/jodit-collaboration` | Docker Hub: the server as a container image |

## Docker in 5 minutes

The fastest path is the published server image `xdsoft/jodit-collaboration`.
Create a `docker-compose.yml`:

```yaml
services:
    collab:
        image: xdsoft/jodit-collaboration:latest
        ports:
            - '8083:8083'
        environment:
            PORT: 8083
            ALLOW_ANONYMOUS: 'true' # demo mode: server assigns guest identities
            STORAGE: postgres
            DATABASE_URL: postgres://collab:collab@postgres:5432/collab
            SNAPSHOT_EVERY: 200
        depends_on:
            - postgres
    postgres:
        image: postgres:16-alpine
        environment:
            POSTGRES_USER: collab
            POSTGRES_PASSWORD: collab
            POSTGRES_DB: collab
        volumes:
            - collab-pg:/var/lib/postgresql/data
volumes:
    collab-pg:
```

```bash
docker compose up
```

Health check: `GET http://localhost:8083/collab/health` →
`{"success":true,"protocol":1}`. The WebSocket endpoint your editor connects
to is `ws://localhost:8083/collab/ws`.

Documents survive restarts because the patch log and snapshots live in Postgres:

```bash
docker compose restart collab
# reconnect the editor; the text is still there
```

> **Note: Demo mode**
> `ALLOW_ANONYMOUS=true` makes every connection get a generated guest identity
> ("Guest Amber Fox"). Production deployments turn it off and plug JWT/session
> checks into the auth hooks instead; see [Authentication](authentication.md).

## As an npm package

If you prefer to run the server inside your own Node.js process (≥ 20) instead
of the container:

```bash
npm install @jodit/collab-server
```

`start()` boots the whole server: REST (health, history) plus the WS
sequencer endpoint at `${routePrefix}/ws`:

```js
import { start } from '@jodit/collab-server';

const server = await start({
	port: 8083,
	auth: { allowAnonymous: true } // demo mode; see authentication.md for real auth
});

console.log(`listening on :${server.port}`);
// ws endpoint:   ws://localhost:8083/collab/ws
// health:        http://localhost:8083/collab/health

// later:
await server.stop();
```

`start()` takes a `Partial<ServerConfig>`; anything you do not pass is filled
in from the environment (`configFromEnv()`). The full option list is in
[Configuration](configuration.md). Typical production shape:

```js
import { start, PostgresStorage } from '@jodit/collab-server';

const server = await start({
	port: 8083,
	storage: new PostgresStorage(process.env.DATABASE_URL),
	snapshotEvery: 200,
	auth: {
		checkAuthentication: async (token, ctx) => {
			const user = await verifyToken(token);
			return user
				? {
						userId: user.id,
						name: user.name,
						color: user.color,
						role: user.role
					}
				: null; // invalid token → connection rejected
		}
	}
});
```

The returned `RunningServer` exposes `httpServer`, `port`, `rooms` and
`stop()`.

## Connecting the editor plugin

On the frontend, `@jodit/collab-plugin` is a normal Jodit plugin. Install it
alongside Jodit:

```bash
npm install @jodit/collab-plugin jodit
```

Register it once, then turn collaboration on per editor through the `collab`
option. The plugin adds its own toolbar buttons and wires up everything
(capture → patches, WebSocket sync, remote cursors, the comments panel and the
tracked-changes panel):

```ts
import { Jodit } from 'jodit'; // or 'jodit-pro'
import collab from '@jodit/collab-plugin';

Jodit.plugins.add('collab', collab);

const editor = Jodit.make('#editor', {
	collab: {
		url: 'wss://example.com/collab/ws',
		docId: 'my-document',
		// A string, or a function called on every (re)connect (JWT refresh).
		// Omit entirely in demo/anonymous mode.
		token: async () => (await fetch('/api/collab-token')).text()
	}
});
```

That is the whole integration. Multiple users editing `my-document` now see
each other's cursors, converge on every change, and share comment threads and
suggestions. The live handle is available as `editor.collab`
(`{ client, api, panel, suggestionsPanel }`) if you need it.

All the `collab` fields beyond `url`/`docId`/`token` are **optional host-UI
hooks**; use them to drive your own presence bar, status indicator, activity
log or replay view:

```ts
Jodit.make('#editor', {
	collab: {
		url,
		docId,
		token,
		comments: true, // mount the comments panel + button (default)
		suggestions: true, // mount the tracked-changes panel + buttons (default)
		presence: true, // mount the participant-avatars bar in the top slot (default)
		onIdentity: self => showMe(self.identity), // your server-assigned name/color
		onPeers: peers => renderPresenceBar(peers), // other participants changed
		onStatus: (status, detail) => setStatus(status), // connecting/online/closed/error
		onEntry: entry => appendToLog(entry), // every sequenced patch (log/replay)
		onError: (code, message, context) => {
			// 'comment'/'suggestion' → show a notice; 'submit' auto-resyncs; 'auth' → session over
			if (context === 'comment') showNotice(message);
		}
	}
});
```

The plugin handles the rest: the `hello`/`welcome` handshake, optimistic local
edits with Jupiter-style rebase, comments, tracked changes, a 30-second
heartbeat to keep idle proxies from closing the socket, automatic reconnect
(resuming with a `sinceSeq` delta when there are no unacknowledged local
edits), and automatic resync when the server refuses a submit (see the
[error reaction table](protocol.md#the-context-field-how-clients-must-react)).

> **Tip**
> You never pass a user name or color; there is no such option. Identity is
> resolved on the server from the token; the strict protocol schemas reject
> any client message that tries to carry one. See
> [Authentication](authentication.md).

> **Note: Building a custom client?**
> The lower-level pieces the plugin composes (`attachCollab` for capture,
> `CollabClient` for transport, `CommentsPanel` / `SuggestionsPanel` for UI)
> are all exported for non-standard integrations. The plugin above is the
> recommended path.

## Next steps

- Read the [protocol spec](protocol.md) to understand (or reimplement) the
  sync algorithm, including the [comments protocol](protocol.md#comments).
- Wire up [real authentication](authentication.md) and read what a
  [security review](security.md) will ask.
- Choose and configure [storage](storage.md).
- Installing for a customer? Follow the
  [on-premise installation guide](on-premise.md); general notes (nginx,
  scaling) are in [Deployment](deployment.md).
- Compare the [cloud and on-premise editions](licensing.md) and how to
  purchase.
