CRDT i Collaborative Editing
Y.js (CRDT Shared Types), Liveblocks (managed platform), PartyKit (serverless WebSockets), Hocuspocus i Tiptap — budowanie Notion-like collaborative editors.
6 narzędzi collaborative editing — porównanie
Y.js, Liveblocks, PartyKit, Hocuspocus, Automerge i ElectricSQL — typ, hosting i zastosowanie.
| Narzędzie | Typ | Hosting | Kiedy |
|---|---|---|---|
| Y.js | CRDT Library | Self-hosted | Offline-first, własny backend, max kontrola |
| Liveblocks | Managed Platform | SaaS (Cloudflare) | Szybki start, gotowe UI, comments, notifications |
| PartyKit | Serverless WebSockets | Cloudflare Workers | Code-first, tanie skalowanie, Y.js backend |
| Hocuspocus | Y.js WebSocket Server | Self-hosted Node.js | Backend dla Y.js, auth, persistence |
| Automerge | CRDT Library (Rust) | Self-hosted | Automerge 2.0 (WASM), offline-first apps |
| Electric SQL | Local-first SQLite sync | Self-hosted/Cloud | SQL queries, offline, sync z Postgres |
Często zadawane pytania
Co to są CRDTs i jak działają algorytmy collaborative editing?
CRDT (Conflict-free Replicated Data Type): struktura danych dla distributed systems. Automatyczne merge bez konfliktów. Bez centralnego serwera. Eventual consistency. Jak działają: każda zmiana ma unikalny ID (UUID + timestamp). Operacje commutative — kolejność nie ma znaczenia. Merge zawsze daje ten sam wynik. Typy CRDT: G-Counter — tylko increment. PN-Counter — increment + decrement. G-Set — tylko dodawanie elementów. OR-Set — add i remove z unique tags. LWW-Register — Last Write Wins. MV-Register — Multi-Value. Sequence CRDT (dla tekstu): Logoot, LSEQ, RGA, Fugue. Ważne dla edytorów tekstu. Operational Transformation (OT): starsza alternatywa. Transformuje operacje przed zastosowaniem. Google Docs używa OT. Trudniejszy w implementacji. Więcej serwerów (transform server). CRDT vs OT: CRDT — P2P możliwe, prostszy server. OT — Google standard, sprawdzony. Lokalna-first architektura: edycja offline. Sync gdy połączenie wraca. Brak 'lost work'. Użytkownik zawsze może pracować. Y.js: najpopularniejsza CRDT implementacja. Shared Types: Y.Map, Y.Array, Y.Text. Providers: WebSocket, WebRTC, IndexedDB. Rich text z ProseMirror/Quill/Tiptap.
Y.js — CRDT biblioteka dla collaborative editing?
Y.js (Kevin Jahns): najpopularniejsza CRDT dla JavaScript. Instalacja: npm install yjs. Shared Types: Y.Doc — root dokument. Y.Map — jak JavaScript Map. Y.Array — jak JavaScript Array. Y.Text — rich text CRDT. Y.XmlFragment — XML/HTML CRDT. Podstawy: const ydoc = new Y.Doc(). const ymap = ydoc.getMap('config'). ymap.set('theme', 'dark'). ymap.observe(event => console.log(event.changes)). Y.Text z Tiptap: npm install @tiptap/extension-collaboration. TiptapExtension: Collaboration.configure({document: ydoc}). CollaborationCursor.configure({provider, user: {name, color}}). Providers: y-websocket: WebSocket sync. const provider = new WebsocketProvider('ws://localhost:1234', 'room', ydoc). y-webrtc: peer-to-peer sync. y-indexeddb: offline persistence. y-partykit: PartyKit integration. Awareness: kursory innych użytkowników. Presence informacje. provider.awareness.setLocalStateField('user', {name: 'Adam', color: '#ff0000'}). provider.awareness.on('change', changes => ...). Undo/Redo: Y.UndoManager([yText, yMap]). manager.undo(). manager.redo(). Wbudowane w Tiptap. Encoding: Y.encodeStateAsUpdate(ydoc). Y.applyUpdate(ydoc, update). Persist do DB — tylko delta. Garbage collection: ydoc.gc = false. Brak GC gdy offline. Uruchom po reconnect. Hocuspocus: backend Y.js server. WebSocket provider backend. Auth, persistence, extensions. Node.js lub Bun.
Liveblocks — managed real-time collaboration platform?
Liveblocks: managed real-time collaboration. Bez własnego serwera. Rooms, Presence, Storage, Comments, Notifications. Instalacja: npm install @liveblocks/client @liveblocks/react. Konfiguracja: createClient({publicApiKey: 'pk_...'}). createRoomContext (z typami). Presence: useMyPresence() — mój stan. useOthers() — inni użytkownicy. updateMyPresence({cursor: {x, y}}). Automatyczne broadcast do pokoju. Storage (CRDT-based): LiveObject, LiveList, LiveMap. useMutation hook: aktualizacja storage. useStorage hook: odczyt. Liveblocks Storage = Y.js pod spodem. Comments: useThreads() — wątki komentarzy. useCreateThread(), useCreateComment(). Notifications: useInboxNotifications(). useMarkInboxNotificationAsRead(). Ready-made UI: @liveblocks/react-ui. Thread, InboxNotification, FloatingComposer. Cursors: Cursor component. Pokazuje kursory innych użytkowników. Avatar i kolor per user. Auth: authEndpoint (server endpoint). Liveblocks weryfikuje token. Supabase/Clerk/NextAuth integration. Liveblocks vs Y.js: Liveblocks — managed, auth, UI components. Y.js — self-hosted, więcej kontroli. Liveblocks — szybszy start, płatny plan. Pricing: darmowy tier (starter). Płatny od enterprise. Liveblocks + Lexical: @liveblocks/react-lexical. Wbudowana collaborative editing. Cursors, presence, storage.
PartyKit — serverless real-time collaboration?
PartyKit (Sunil Pai, Cloudflare): serverless real-time platform. WebSockets na Cloudflare Workers. Durable Objects dla state. npm install partykit. Serwer PartyKit: src/server.ts. import {Party} from 'partykit/server'. export default class MyParty implements Party.Server { async onConnect(connection, room) { connection.send('hello') } async onMessage(message, sender, room) { room.broadcast(message) } }. Deploy: npx partykit deploy. Rooms: partysocket — klient WebSocket. import PartySocket from 'partysocket'. const socket = new PartySocket({host: 'myparty.youruser.partykit.dev', room: 'document-123'}). socket.addEventListener('message', handler). socket.send(JSON.stringify({type: 'update', data})). Persistence: Party.Storage — durable storage. await room.storage.put('state', data). await room.storage.get('state'). Durable Objects pod spodem. Y.js + PartyKit: y-partykit provider. npm install y-partykit. PartyKitServer (z y-partykit) jako serwer. new YPartyKitProvider('myhost.partykit.dev', 'room', ydoc). Presence w PartyKit: broadcast presence na każdy ruch. Filtruj własne connection. Skalowalność: Cloudflare global network. Niski latency. Autoscaling. Tańszy niż Liveblocks dla dużych użyć. PartyKit vs Liveblocks: PartyKit — code-first, Cloudflare. Liveblocks — managed, więcej features. PartyKit — tańszy przy scale. Liveblocks — gotowe UI components.
Jak zbudować collaborative editor z React, Tiptap i Y.js?
Stack: Tiptap (editor) + Y.js (CRDT) + Hocuspocus (backend) + React. Instalacja: npm install @tiptap/react @tiptap/starter-kit @tiptap/extension-collaboration @tiptap/extension-collaboration-cursor yjs @hocuspocus/provider. Konfiguracja: const ydoc = new Y.Doc(). const provider = new HocuspocusProvider({url: 'ws://localhost:1234', name: 'doc-1', document: ydoc}). Tiptap setup: useEditor({extensions: [StarterKit.configure({history: false}), Collaboration.configure({document: ydoc}), CollaborationCursor.configure({provider, user: {name: currentUser.name, color: randomColor()}})]}). Kursory innych: automatyczne z CollaborationCursor. CSS dla komentarzy. Hocuspocus server: npm install @hocuspocus/server. import {Server} from '@hocuspocus/server'. const server = Server.configure({port: 1234, extensions: [new Database({fetch: async({documentName}) => getFromDB(documentName), store: async({documentName, state}) => saveToDB(documentName, state)})]}). server.listen(). Offline support: y-indexeddb persist offline. const indexeddbProvider = new IndexeddbPersistence('doc-name', ydoc). indexeddbProvider.on('synced', () => console.log('loaded from db')). Gdy online: WebSocket sync z Hocuspocus. Merge automatyczny przez Y.js. Awareness kursory: type AwarenessState = {user: {name: string, color: string}, cursor: DecorationRange}. useEffect(() => { provider.setAwarenessField('user', currentUser) }). Undo/Redo: Tiptap History extension — wyłącz (conflict z Y.js). Y.UndoManager dla collaborative undo. Collaboration.configure — wbudowany undo. Persystencja: Hocuspocus Database extension. Postgres lub MongoDB. Binary Y.js state — małe delty. Snapshots: Y.encodeStateAsUpdate(ydoc). Wersjonowanie dokumentów.
Powiązane artykuły
Skontaktuj się z nami
Porozmawiajmy o Twoim projekcie. Bezpłatna wycena w ciągu 24 godzin.
Wyślij zapytanie
Telefon
+48 790 814 814
Pon-Pt: 9:00 - 18:00
adam@fotz.pl
Odpowiadamy w ciągu 24h
Adres
Plac Wolności 16
61-739 Poznań
Godziny pracy
Wolisz porozmawiać?
Zadzwoń teraz i porozmawiaj z naszym specjalistą o Twoim projekcie.
Zadzwoń teraz