Kevin Jahns

State Synchronization for Collaborative Apps

Yjs

What is Yjs?

  • A CRDT document (Y.Map, Y.Text, Y.Array, Y.Xml*)
  • In-memory
  • Network Agnostic
  • Huge ecosystem

Realtime & Automatic Conflict Resolution

Shared Types

  • Like normal data types - with superpowers!
  • They sync automatically
  • Observable

Shared Type Example

import * as Y from 'yjs'

const ydoc = new Y.Doc()

const webrtcProvider = new WebrtcProvider('room-name', ydoc, { password: 'optional-room-password' })
// const websocketProvider = new WebsocketProvider(url, 'room-name', ydoc)
// const matrixProvider = new MatrixProvider(ydoc, matrixClient, {type: "alias",alias: "matrix-room-alias"});

const ymap = ydoc.getMap('map')
const yarray = ydoc.getArray('array')
const ytext = ydoc.getText('text')
const yxml = ydoc.getXmlElement('el')

ymap.observe(event => {
  console.log(event.changes.keys) // { "my key": { action: 'add', oldValue: undefined } }
})

ymap.set('my key', 'new value')

Affine BlockEditor build on top of Yjs Shared Types

Editors with Yjs integration

ProseMirror

CodeMirror

Monaco Editor

Gutenberg / Wordpress

SyncedStore

SyncedStore

import React from "react";
import { useSyncedStore } from "@syncedstore/react";
import { store } from "./store";

export default function App() {
  const state = useSyncedStore(store);

  return (
    <div>
      <p>Todo items:</p>
      <ul>
        {state.todos.map((todo, i) => (
          <li key={i} style={{ textDecoration: todo.completed ? "line-through" : "" }}>
            <label>
              <input type="checkbox" checked={todo.completed} onClick={() => (todo.completed = !todo.completed)} />
              {todo.title}
            </label>
          </li>
        ))}
      </ul>
      <input
        onKeyPress={(event) => {
          if (event.key === "Enter") {
            state.todos.push({ completed: false, title: event.target.value });
            target.value = "";
          }
        }}
      />
    </div>
  );
}

SyncedStore

Yjs Ecosystem

  • y-webrtc
  • y-websocket
  • hocuspocus
  • liveblocks
  • y-sweet
  • yrs-warp
  • matrix-crdt
  • ..
  • y-prosemirror
  • y-quill
  • y-codemirror
  • y-ace
  • y-monaco
  • lexical
  • ...

Editor Bindings

Connectors

Persistence

  • y-indexeddb
  • y-leveldb
  • ystream

Cloud Providers

  • Affine Cloud
  • Liveblocks
  • y-sweet Cloud
  • Hocuspocus Cloud
  • Partykit / Cloudflare

Y CRDT

Yjs ported to different programming languages

Work of Bartosz Sypytkowski and many others

Ycs

twitter.com/kevin_jahns

Yjs / Localfirst Meetup Shanghai 2024

By Kevin Jahns

Yjs / Localfirst Meetup Shanghai 2024

  • 126