Skip to content
Edytor
Esc
↑↓navigate↵open⌘Jpreview
Slate's flexibility, Svelte's ergonomics

The block editor for Sveltecollaborative by default.

Render every block with your own Svelte snippets, hook into every edit with plugins, and let people write together — online, offline, and across tabs — on a Yjs v14 engine with a Durable Object server.

$pnpm add edytor

Open this page in a second tab or on another device — you are editing the same document, synced through a Cloudflare Durable Object.

Built for real documents

A small editing engine, not a black box.

A readable JSON block model on a CRDT, commands you can intercept, and a rendering layer you control — from a single textarea replacement to a collaborative workspace.

Your components, every block

Blocks, marks, and inline atoms render through your own Svelte snippets. The core owns the text; you own the markup around it.

Plugins that can veto anything

Every command is prepared before it writes. Plugins see each planned step and can veto, replace, or extend it.

Real-time collaboration

One shared document for any number of views and peers, with presence cursors and conflict-free merges of moves, splits, and joins.

Offline first, cross-tab

A local copy in IndexedDB and a BroadcastChannel between tabs: edits made offline survive reloads and sync on reconnect.

A Durable Object server

Deploy the ready-made room or attach a document to your own Durable Object: SQLite storage, store-before-ack, identity binding, hibernation.

Notion-style editing

Notion's look and keys out of the box: a theme stylesheet, slash and block menus, the toolbar, markdown and shortcuts.

One component. One Worker.

The same setup that runs the live editor above: a Svelte view and a Durable Object room you deploy on your own Cloudflare account.

<script lang="ts">
  import { Edytor } from "edytor";
</script>

<Edytor
  server="wss://rooms.example.com/rooms"
  room={documentId}
  params={{ token }}
  actor={{ id: userId, name: userName }}
/>
import {
  DocumentRoom, requestedReplica, routeDocumentSocket
} from "edytor/cloudflare";

export { DocumentRoom };

export default {
  fetch(request, env) {
    const id = new URL(request.url).pathname.split("/").pop();
    return routeDocumentSocket(request, env.ROOMS, id, async (req) => {
      const user = await verify(req); // your auth
      return user && { userId: user.id, replica: requestedReplica(req) };
    });
  },
};

Everything from a paragraph to a workspace.

The editing features people expect, and the extension points to build the ones they don't yet.

Start with one paragraph. Grow into a workspace.

Drop the component into a SvelteKit page, then add plugins, your own blocks, and a collaboration room when you need them.