Introduction
Use these guides to add Yjs-based CRDT to your project with Velt. The core library supports multiple store types — pick the one that matches your data shape. Use the React Hook wrapper for the fastest integration in React apps, or the core library for other frameworks and custom implementations.Setup
Step 1: Install Dependencies
- React / Next.js
- Other Frameworks
Step 2: Initialize Velt in your app
Initialize the Velt client and set the document context. This is required for the collaboration engine to work.- React / Next.js
- Other Frameworks
Wrap your app with
VeltProvider and use useSetDocument to scope the collaborative session. Follow the Velt Setup Docs for full setup.Step 3: Choose a store type
Each store type maps to a Yjs shared data structure. Pick the one that matches your use case and follow its setup guide:Array Store
Collaborative ordered lists — todo apps, item collections, ordered datasets.
Map Store
Collaborative key-value pairs — settings, metadata, configuration objects.
Text Store
Collaborative plain text — notepads, code editors, text fields.
XML Store
Collaborative XML/tree data — outlines, structured documents, custom tree editors.
Step 4: Event subscriptions (optional)
- React / Next.js
- Other Frameworks
Use the
useCrdtEventCallback hook to listen for CRDT events:Step 5: Custom encryption (optional)
- React / Next.js
- Other Frameworks
Pass a custom
VeltEncryptionProvider to VeltProvider to encrypt/decrypt CRDT state before it is stored on the backend.APIs
React: useStore()
React hook that creates and manages a CRDT store. Handles initialization, real-time subscriptions, and cleanup automatically.- Signature:
useStore<T>(config: UseStoreConfig<T>) - Params:
storeId: Unique document identifier.type: Yjs data type:'text','map','array','xml', or'xmltext'.initialValue: Initial value applied if remote state is empty.debounceMs: Throttle interval (ms) for backend writes. Default:0.enablePresence: Enable presence tracking. Default:true.forceResetInitialContent: Iftrue, always reset toinitialValueon init. Default:false.onError: Error callback.veltClient: Explicit Velt client. Falls back toVeltProvidercontext.
- Returns:
UseStoreReturn<T>value: Current store value, reactively updated.update: Replace the entire store value.store: Underlying store instance for advanced use.isLoading:truewhile the store is initializing.isSynced:truewhen the store is connected and synced.status: Connection status:'connecting','connected', or'disconnected'.error: Error object if initialization failed.versions: List of saved versions.saveVersion: Save a named snapshot.getVersions: List all saved versions.getVersionById: Get a specific version by ID.restoreVersion: Restore to a saved version.setStateFromVersion: Apply a version’s state to the document.
React: useAwareness()
React hook that wraps the Yjs Awareness instance from a store, providing reactive remote peer states and a stable setter for local awareness state.- Params:
store: Store<any> | null— The store instance fromuseStore()(safe to passnull) - Returns:
UseAwarenessReturn<T>remoteStates: Awareness states of all remote peers.localState: Current local awareness state.setLocalState: Set or clear the local awareness state.
Non-React: createVeltStore()
Convenience factory that creates aStore, calls initialize(), and returns it. Returns null if initialization fails.
- Params: StoreConfig
id: Unique document identifier.type: Yjs data type:'text','map','array', or'xml'.initialValue: Initial value applied if remote state is empty.veltClient: Velt client instance (frominitVelt()). Required for sync.debounceMs: Throttle interval (ms) for backend writes. Default:0.enablePresence: Enable presence tracking. Default:true.forceResetInitialContent: Iftrue, always reset toinitialValueon init. Default:false.contentKey: Content key for Yjs shared types. Default:'content'.userId: User identifier for update attribution.collection: Collection/namespace for document grouping.logLevel: Log level:'silent','error','warn','debug'. Default:'error'.
- Returns:
Promise<Store<T> | null>
Store Methods
These methods are available on thestore instance (from useStore or createVeltStore):
update()
Update the store value and sync to peers.- Params:
newValue: T - Returns:
void
getValue()
Get the current store value. For map stores, returns thetoJSON() representation of the underlying Y.Map as a plain JavaScript object.
- Returns:
T
subscribe()
Subscribe to changes in the store.- Params:
(newValue: T) => void - Returns:
() => void(unsubscribe function)
destroy()
Clean up resources when done with the store. Automatic in React via the hook.- Returns:
void
getDoc()
Get the underlying Yjs document.- Returns:
Y.Doc
getProvider()
Get the provider instance for the store.- Returns:
Provider
getText()
Get the Y.Text instance if store type is ‘text’.- Returns:
Y.Text | null
getXml()
Get the Y.XmlFragment instance if store type is ‘xml’.- Returns:
Y.XmlFragment | null
getAwareness()
Get the Awareness instance for cursor/presence tracking.- Returns:
Awareness
Version Methods
Available on both theuseStore hook return and the store instance:
saveVersion()
Save a snapshot of the current state as a named version.- Params:
versionName: string - Returns:
Promise<string>
getVersions()
Fetch all saved versions.- Returns:
Promise<Version[]>
getVersionById()
Fetch a specific version by ID.- Params:
versionId: string - Returns:
Promise<Version | null>
restoreVersion()
Restore the store to a specific version using its ID.- Params:
versionId: string - Returns:
Promise<boolean>
setStateFromVersion()
Restore the store state from a specific version object.- Params:
version: Version - Returns:
Promise<void>
Custom Encryption
Encrypt CRDT data before it’s stored in Velt by registering a custom encryption provider. For CRDT methods, input data is of typeUint8Array | number[].
- React / Next.js
- Other Frameworks
CRDT Event Subscriptions
on
Subscribe to CRDT events. Currently supports theupdateData event which fires when CRDT data changes.
- Params:
eventType: "updateData" - Returns:
Observable<CrdtUpdateDataEvent>
- React / Next.js
- Other Frameworks
Using Hook:Using API:
Low-Level Message APIs
These APIs provide direct access to the CRDT message stream for custom implementations.pushMessage()
Push a raw Yjs message into the unified message stream.- Params:
CrdtPushMessageQuery - Returns:
Promise<void>
- React / Next.js
- Other Frameworks
onMessage()
Subscribe to incoming messages on the unified message stream. Returns an unsubscribe function.- Params:
CrdtOnMessageQuery - Returns:
() => void
- React / Next.js
- Other Frameworks
getMessages()
Retrieve historical messages from the unified message stream.- Params:
CrdtGetMessagesQuery - Returns:
Promise<CrdtMessageData[]>
- React / Next.js
- Other Frameworks
getSnapshot()
Retrieve the latest CRDT state snapshot for a document.- Params:
CrdtGetSnapshotQuery - Returns:
Promise<CrdtSnapshotData | null>
- React / Next.js
- Other Frameworks
saveSnapshot()
Persist a CRDT state snapshot for a document.- Params:
CrdtSaveSnapshotQuery - Returns:
Promise<void>
- React / Next.js
- Other Frameworks
pruneMessages()
Delete historical messages older than a given timestamp from the message stream.- Params:
CrdtPruneMessagesQuery - Returns:
Promise<void>
- React / Next.js
- Other Frameworks
Migration Guide: v1 to v2
React
Overview
The v2 API replacesuseVeltCrdtStore() with useStore(). The new hook uses storeId instead of id, adds reactive status/isSynced/error state, and supports forceResetInitialContent.
Key Changes
| Aspect | v1 (deprecated) | v2 (current) |
|---|---|---|
| Entry point | useVeltCrdtStore(config) | useStore(config) |
| Store ID field | id | storeId |
| Status tracking | Not available | isLoading, isSynced, status |
| Error handling | Not available | onError callback + error state |
| Force reset | Not available | forceResetInitialContent |
| Version management | Same methods | Same methods |
| Cleanup | Automatic on unmount | Automatic on unmount |
Step-by-Step
1. Replace the hook:Legacy API (v1)
useVeltCrdtStore() (deprecated)
React hook to create and sync a collaborative CRDT store. Internally delegates touseStore (v2) via a compatibility wrapper.
- Signature:
useVeltCrdtStore<T>(config) - Params:
id: Unique identifier for the store.type: Type of Yjs data structure ('text'|'array'|'map'|'xml').initialValue: Optional initial value for the store.debounceMs: Optional debounce time for update propagation (ms).enablePresence: Optional boolean to enable realtime presence tracking (default:true).
- Returns: Store properties and methods (
value,update,store,versions,saveVersion,getVersions,getVersionById,restoreVersion,setStateFromVersion)
Debugging
Use the Velt Chrome Extension or thewindow.VeltCrdtStoreMap debugging interface to inspect and monitor your CRDT stores.
window.VeltCrdtStoreMap
window.VeltCrdtStoreMap is a global debugging interface that exposes all active CRDT stores in your application. It’s automatically created and maintained by the Velt CRDT library.
get()
Get a store by its ID.- Params:
id(optional): Store ID. If omitted, returns the first registered store.
- Returns:
VeltCrdtStore | undefined- Store object methods:
getValue(): Get the current value from the storesubscribe(callback: (value: any) => void): Subscribe to changes. Returns an unsubscribe function.
- Store object methods:
- Basic Usage
- Inspect Store

