---
title: Collaboration
description: How edytor shares one document between views, browser tabs and people, and which setup to pick.
icon: users
---

Every edytor document is a CRDT: edits from any number of views, tabs and people merge on their own, without a central lock and without losing work made offline. This section covers the document object, the providers that persist and transport it, presence, and the editing rules users see when they edit together.

## How it fits together

One document is one `EdytorDocument`. It owns the CRDT state, a document API (the facade), one undo history, one awareness instance for presence, and the local author identity. Views render it; providers keep it in sync.

```mermaid
flowchart LR
  V1[Edytor view] --> D[EdytorDocument]
  V2[Edytor view] --> D
  H[Headless code] --> D
  D --> I[(IndexedDB copy)]
  D --> W[WebSocket provider]
  I -. BroadcastChannel .- T[Other tabs]
  W <--> R[DocumentRoom<br/>Durable Object]
```

- **The document** is created with `createDocument` or restored with `loadDocument`. It works with no view at all (Node, SSR, tests) or behind any number of `<Edytor>` views. See [Documents](/docs/collaboration/documents).
- **A sync** attaches a provider to the document. On a view, the `room` and `server` props build it for you; for a shared document, attach a factory such as `createWebsocketSync(options)` with `document.attachSync(…)`. The provider lives as long as the document, not the view.
- **Awareness** carries presence: who is here, their name and color, and their selection. Every view and provider shares the document's single awareness instance. See [Presence](/docs/collaboration/presence).
- **The room** is `DocumentRoom`, a Cloudflare Durable Object that edytor ships, or any Durable Object of yours with `attachDocument(this)`. You deploy it on your own account; it authorizes sockets through your code, stores the document in SQLite and relays edits. See [Server](/docs/server/quick-start).

When two replicas meet, whether a tab and the server or two tabs, each tells the other what it already holds, and each sends back what the other lacks. There is no "last save wins": offline edits merge the next time a connection opens.

## Choose your setup

**[Local only](/docs/collaboration/documents)**

One browser, no persistence. Pass a `value` or a `document` and edit. Several views can share it.

**[IndexedDB](/docs/collaboration/persistence)**

Keep the document in the browser. Survives reloads and syncs open tabs, with no server.

**[WebSocket room](/docs/collaboration/websocket)**

Real-time editing between people through the Durable Object room, with a local copy for offline work.

### Local only

```svelte
<script lang="ts">
  import { Edytor } from 'edytor';

  const value = { children: [{ type: 'paragraph', content: [{ text: 'Hello' }] }] };
</script>

<Edytor {value} />
```

### IndexedDB

`room` alone names a local copy:

```svelte
<Edytor room="notes/today" />
```

### WebSocket room

Add a `server`, and the view joins the room `<server>/<room>`:

```svelte
<Edytor
  server="wss://rooms.example.com/rooms"
  room="doc-42"
  params={{ token }}
  actor={{ id: userId, name: 'Ada' }}
/>
```

The room keeps a local IndexedDB copy too, so the third setup also covers the second. `params` travel with each connection (see the [server quick start](/docs/server/quick-start)); `actor` names the author for undo, attribution and presence.

:::note
`room` and `server` are read once, when the view mounts, and only by editable views; wrap the view in `{#key documentId}` to switch documents. A `readonly` view connects nothing; attach the sync to a shared document instead (see [Documents](/docs/collaboration/documents#attach-a-provider)). For a custom provider, pass a factory as `sync`.
:::

## In this section

**[Documents](/docs/collaboration/documents)**

`createDocument`, `loadDocument`, readiness, several views and headless use.

**[Persistence](/docs/collaboration/persistence)**

IndexedDB, the local copy, offline behavior and cross-tab sync.

**[WebSocket](/docs/collaboration/websocket)**

`createWebsocketSync` options, provider events, saved state and reconnects.

**[Presence](/docs/collaboration/presence)**

User names and colors, remote carets and selections.

**[Concurrent editing](/docs/collaboration/concurrent-editing)**

What people see when they delete, undo, split and move at the same time.

**[Server](/docs/server/quick-start)**

Deploy the Durable Object room in a few steps.
