Core concepts
Documents
Documents are the unit of sync in Syndra typed JSON trees that merge automatically.
A document is a JSON value identified by a path such as lists/groceries. Every client that opens the same path shares the same state.
const doc = syndra.doc("boards/roadmap")Anatomy of a document
Under the hood, each document is a CRDT: a history of small operations rather than a single blob. That’s what lets two people edit the same document at the same time without overwriting each other.
| Property | Type | Description |
|---|---|---|
path |
string |
Unique identifier within the project. |
state |
T |
The current merged value. |
version |
VersionVector |
Which operations this replica has seen. |
status |
'synced' | 'pending' | 'offline' |
Whether local changes have reached the server. |
Reading
Read the current value synchronously, or subscribe to changes:
const current = doc.get()
const unsubscribe = doc.subscribe((state, meta) => {
console.log(state, meta.origin) // 'local' | 'remote'
})Selecting part of a document
Pass a selector to only re-run when a slice changes. This keeps large documents cheap to observe.
doc.subscribe(
(state) => state.items.length,
(count) => (badge.textContent = String(count)),
)Writing
All writes go through update. The draft is a mutable proxy change it however you like, and Syndra turns your edits into operations.
doc.update((draft) => {
draft.title = "Q3 Roadmap"
draft.columns[0].cards.push({ id: "c_91", text: "Ship presence v2" })
})Lifecycle
Documents load lazily and are released when nothing references them. Call doc.dispose() in long-lived apps when a view unmounts; framework bindings do this for you.