Real-Time CRDTs · AI Writing Assistant · Live Presence · Conflict-Free Collaboration
Features · Architecture · How CRDTs Work · AI Assistant · Quick Start · Roadmap
CollabEdit Pro is a production-grade collaborative text editor built on Conflict-free Replicated Data Types (CRDTs) via Yjs — the same technology powering Notion, Linear, and Figma's multiplayer features.
Unlike tutorial CRUD apps, this solves a genuinely hard distributed systems problem: how do you merge simultaneous edits from multiple users with zero conflicts, zero data loss, and millisecond latency?
Built to deeply understand the engineering behind Google Docs — not just use it.
| Feature | Implementation |
|---|---|
| Conflict-free editing | Yjs CRDT — mathematically guaranteed merge correctness |
| Real-time sync | y-websocket binary protocol — millisecond latency |
| Offline support | Yjs IndexedDB persistence — edits survive disconnection |
| Live cursors | Real-time cursor and selection position for all collaborators |
| Presence indicators | WhatsApp-style activity notifications per user |
| Capability | Model |
|---|---|
| Instant summarization | Groq Llama 3.3 (ultra-low latency inference) |
| Tone adjustment | Formal / Casual / Persuasive / Technical |
| Smart rephrasing | Context-aware rewrite suggestions |
| In-editor sidebar | Non-blocking async UX — never interrupts your flow |
- Floating Lexicon Card — live word count, character count, reading time estimate
- Emoji reaction layer — heartbeat-synchronized reactions that float across the screen
- Rich formatting — H1-H3 headings, task lists, bulleted lists, bold/italic/underline
- Snapshot management — manual version saves to MongoDB Atlas for document recovery
- Premium aesthetics — custom CSS variables, smooth animations, dark-mode ready
┌─────────────────────────────────────────────────────────────────┐
│ Browser Clients │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ User A │ │ User B │ │ User C │ │
│ │ TipTap │ │ TipTap │ │ TipTap │ │
│ │ Editor │ │ Editor │ │ Editor │ │
│ │ + │ │ + │ │ + │ │
│ │ Yjs Doc │ │ Yjs Doc │ │ Yjs Doc │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
└──────────┼────────────────── ┼────────────────── ┼─────────────┘
│ WebSocket │ WebSocket │ WebSocket
│ (binary Yjs ops) │ │
┌──────────▼────────────────── ▼────────────────── ▼─────────────┐
│ y-websocket Coordinator │
│ Broadcasts CRDT updates to all peers │
│ Maintains awareness (cursors, presence) │
└──────────────────────┬──────────────────────────────────────────┘
│
┌────────────┼──────────────┐
│ │ │
┌──────▼──────┐ ┌───▼────┐ ┌──────▼──────┐
│ MongoDB │ │ Groq │ │ Express │
│ Atlas │ │ API │ │ REST API │
│ Snapshots │ │ LLM │ │ CRUD │
└─────────────┘ └────────┘ └─────────────┘
User types "Hello"
│
▼
TipTap captures keystroke
│
▼
Yjs encodes as CRDT operation (not the text — the operation)
│
▼
y-websocket sends binary update to coordinator (< 1ms)
│
▼
Coordinator broadcasts to all connected peers
│
▼
Each peer's Yjs instance merges the operation
(mathematically guaranteed to converge regardless of order)
│
▼
TipTap re-renders with merged state
│
▼
All users see identical document ✅
This is the core engineering insight behind CollabEdit Pro. Understanding this separates it from every other "collaborative editor" tutorial project.
User A types "Hello" at position 0
User B types "World" at position 0 simultaneously
Naive approach: Last write wins → one edit is LOST ❌
Lock-based: User B waits for A to finish → terrible UX ❌
Yjs uses a sequence CRDT where every character is assigned a globally unique identifier — not just a position.
Instead of: "Insert 'H' at index 0"
Yjs stores: "Insert 'H' with ID [clientA:1], after ID [root]"
Instead of: "Insert 'W' at index 0"
Yjs stores: "Insert 'W' with ID [clientB:1], after ID [root]"
Now when these operations arrive in ANY order on ANY peer:
Both operations can be applied independently
Both characters survive
Document converges to the same state on all peers ✅
- Operations must be commutative (order doesn't matter)
- Operations must be idempotent (applying twice = applying once)
- Concurrent inserts at the same position need a deterministic tiebreaker
- Deletions must tombstone rather than remove (to handle late-arriving inserts)
Yjs handles all of this — and CollabEdit Pro puts it to work in a real editor with real users.
Powered by Groq's Llama 3.3 — currently the fastest LLM inference API available (300+ tokens/sec).
User selects text → clicks AI action → result appears in sidebar
Total latency: ~400ms
(Groq inference: ~200ms + network: ~150ms + render: ~50ms)
// Summarize
prompt: `Summarize the following text concisely:\n\n${selectedText}`
// Rephrase
prompt: `Rephrase the following text while preserving meaning:\n\n${selectedText}`
// Tone adjustment
prompt: `Rewrite the following text in a ${tone} tone:\n\n${selectedText}`
// tone: "formal" | "casual" | "persuasive" | "technical"For in-editor assistance, latency is everything. A 2-3 second OpenAI response breaks the writing flow. Groq's hardware-accelerated inference keeps it under 400ms — fast enough to feel instant.
| Layer | Technology | Why This Choice |
|---|---|---|
| Editor | TipTap | Headless, extensible, Yjs-native integration |
| CRDT | Yjs | Battle-tested, used by Notion and Figma |
| Sync | y-websocket | Binary protocol, 10x lighter than JSON |
| Frontend | React 18 + Vite | Concurrent rendering for smooth live updates |
| Styling | Tailwind + CSS Variables | Premium theming without runtime overhead |
| Backend | Node.js + Express | Non-blocking I/O matches WebSocket architecture |
| Database | MongoDB Atlas | Flexible document model for editor snapshots |
| AI | Groq Llama 3.3 | Fastest inference API — 300+ tokens/sec |
| Icons | Lucide React | Consistent, lightweight icon system |
node >= 18
npm >= 9
MongoDB (local or Atlas URI)
Groq API key — free at console.groq.comgit clone https://github.com/PrajwaL-N-TECHIE/CollabEdit-Pro.git
cd CollabEdit-ProServer (server/.env):
PORT=1234
MONGODB_URI=mongodb://localhost:27017/collabedit
GROQ_API_KEY=your_groq_api_key_hereClient (client/.env.local):
VITE_WS_URL=ws://localhost:1234
VITE_SERVER_URL=http://localhost:5000cd server
npm install
node server.js
# y-websocket coordinator running on ws://localhost:1234
# Express API running on http://localhost:5000cd client
npm install
npm run dev
# Visit http://localhost:5173Open http://localhost:5173 in two separate browser windows. Start typing in one — watch edits appear instantly in the other. Try typing simultaneously — notice zero conflicts. That's Yjs CRDTs working.
CollabEdit-Pro/
├── client/
│ ├── src/
│ │ ├── components/
│ │ │ ├── Editor.jsx # TipTap + Yjs integration
│ │ │ ├── Toolbar.jsx # Formatting controls
│ │ │ ├── AIAssistant.jsx # Groq sidebar
│ │ │ ├── LexiconCard.jsx # Floating word/char counter
│ │ │ ├── EmojiReactions.jsx # Floating reaction layer
│ │ │ └── Presence.jsx # Live user indicators
│ │ ├── hooks/
│ │ │ ├── useCollaboration.js # Yjs + y-websocket setup
│ │ │ └── useAI.js # Groq API calls
│ │ └── App.jsx
│ ├── .env.local
│ └── package.json
├── server/
│ ├── server.js # y-websocket + Express
│ ├── routes/
│ │ └── snapshots.js # MongoDB snapshot CRUD
│ ├── .env
│ └── package.json
└── README.md
Why TipTap over Slate or Quill?
TipTap is the only major editor with first-class Yjs integration via @tiptap/extension-collaboration. Slate requires significant custom CRDT work. Quill's architecture makes Yjs integration brittle.
Why binary WebSocket over Socket.io? Yjs encodes operations in binary (not JSON). y-websocket transmits them as-is — no serialization overhead. Socket.io would add JSON stringification, increasing bandwidth by ~3x for high-frequency ops.
Why MongoDB for snapshots? Editor state is a rich document — nested marks, formatting, metadata. MongoDB's flexible document model stores TipTap's JSON output natively without schema migrations. PostgreSQL with JSONB would also work but adds unnecessary complexity.
Why not use operational transforms (OT) like Google Docs? OT requires a central server to order all operations — this creates a single point of failure and adds round-trip latency. CRDTs are peer-to-peer: operations can be applied locally immediately and merged later, enabling true offline support.
- Yjs CRDT real-time sync
- TipTap rich text editor
- Live cursors and presence
- Groq AI assistant
- MongoDB snapshot persistence
- Floating emoji reactions
- Lexicon card (word/char/reading time)
- Offline persistence via IndexedDB
- Table and image support
- Document sharing via invite link
- Comment threads (anchored to text ranges)
- Export to PDF / Markdown / DOCX
- Self-hosted y-websocket with Redis pub/sub for horizontal scaling
- Yjs Documentation — Core CRDT library
- TipTap Collaboration Guide — Editor + Yjs integration
- A Conflict-Free Replicated JSON Datatype — Academic paper behind Yjs
- Figma's Multiplayer Engineering — How Figma solved this at scale
- Groq API Docs — LLM inference
PRs are welcome! Especially for items on the roadmap.
git clone https://github.com/PrajwaL-N-TECHIE/CollabEdit-Pro.git
cd CollabEdit-Pro
# Make your changes
# Open a PR with a clear description of what you changed and whyPrajwal N — AI Engineer Intern @ InFynd | Chief Architect @ EduSpine
12x National Tech Winner building at the intersection of distributed systems and AI infrastructure.
If this helped you understand CRDTs or collaborative systems, drop a ⭐ — it helps others find it!
Built to understand the hard problems. Not just ship features. 🔥