Fundamentals
Core Yjs concepts you need to understand before designing collaborative data structures.
Overview
Yjs provides a set of shared data types that automatically synchronize across clients and resolve conflicts. Understanding these primitives is essential for building robust collaborative applications.
Topics
- Shared Types - Y.Map, Y.Array, Y.Text, and Y.XmlFragment
- Document Structure - Organizing your Y.Doc effectively
- Internals - How Yjs works under the hood (optional deep dive)
Key Concepts
Shared Types Are Not Regular Objects
Yjs shared types look similar to JavaScript objects and arrays, but they behave differently:
// Regular JavaScript - changes are local only
const obj = { name: 'Alice' }
obj.name = 'Bob' // Only visible locally
// Yjs shared type - changes synchronize
const yMap = yDoc.getMap('user')
yMap.set('name', 'Alice')
yMap.set('name', 'Bob') // Syncs to all connected clients
Documents Contain All Shared Data
A Y.Doc is the root container for all collaborative data. Different parts of your application access different top-level keys:
const yDoc = new Y.Doc()
// Each getMap/getArray/getText creates a named root-level shared type
const cells = yDoc.getMap('cells') // Spreadsheet data
const order = yDoc.getArray('rowOrder') // Row ordering
const meta = yDoc.getMap('metadata') // Document metadata
Changes Must Go Through Yjs APIs
Yjs only tracks changes made through its APIs. Direct mutation of extracted values does not synchronize:
// WRONG - changes not tracked
const obj = yMap.get('config')
obj.theme = 'dark' // This change is lost!
// CORRECT - use Yjs API
yMap.set('config', { ...yMap.get('config'), theme: 'dark' })