API Usage
Mistakes when calling Yjs methods.
Mutating Objects After Insertion
// WRONG
const config = { theme: 'light' }
yMap.set('config', config)
config.theme = 'dark' // NOT synced!
Yjs snapshots on set(). Later mutations don’t propagate.
Fix: Create new objects, or use nested Y.Map for granular updates:
yMap.set('config', { ...yMap.get('config'), theme: 'dark' })Moving Shared Types Between Parents
// WRONG
const items = folder1.get('items') // Y.Array
folder2.set('items', items) // Error!
Shared types can only have one parent.
Fix: Copy data to new shared type, delete old.
Creating New Instances Instead of Accessing
// WRONG
function addItem(item) {
const items = new Y.Map() // Disconnected!
items.set(item.id, item)
}new Y.Map() is unattached. Use yDoc.getMap().
Not Using Transactions
// WRONG: 2N syncs, 2N observer events
for (const item of items) {
content.set(item.id, item)
order.push([item.id])
}Fix: Wrap in transact():
yDoc.transact(() => {
for (const item of items) {
content.set(item.id, item)
order.push([item.id])
}
})Forgetting trackedOrigins
// WRONG: captures remote changes too
const undoManager = new UndoManager([content])Without trackedOrigins, undo captures collaborators’ changes.
Fix:
const undoManager = new UndoManager([content], {
trackedOrigins: new Set(['user-action'])
})
yDoc.transact(() => { ... }, 'user-action')Checklist
- Never mutate after
set() - Don’t move shared types between parents
- Use
yDoc.getMap(), notnew Y.Map() - Wrap related changes in
transact() - Configure UndoManager with
trackedOrigins