> ## Documentation Index
> Fetch the complete documentation index at: https://velt.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Core Setup

> Setup Multiplayer Editing for any frameworks or custom implementations.

## 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

> [tab] React / Next.js
>
> ```bash theme={null}
> npm install @veltdev/crdt-react @veltdev/crdt @veltdev/react
> ```

> [tab] Other Frameworks
>
> ```bash theme={null}
> npm install @veltdev/crdt @veltdev/client
> ```

### 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.

> [tab] React / Next.js
>
> Wrap your app with `VeltProvider` and use `useSetDocument` to scope the collaborative session. Follow the [Velt Setup Docs](https://velt.dev/docs/get-started/quickstart.md) for full setup.
>
> ```tsx theme={null}
> import { VeltProvider, useSetDocument } from '@veltdev/react';
>
> function App() {
>   return (
>     <VeltProvider apiKey="YOUR_API_KEY">
>       <YourApp />
>     </VeltProvider>
>   );
> }
>
> function YourApp() {
>   useSetDocument('my-document-id', { documentName: 'My Document' });
>   return <YourComponent />;
> }
> ```

> [tab] Other Frameworks
>
> Initialize the Velt SDK with `initVelt()`, set the document context, and authenticate a user.
>
> ```js theme={null}
> import { initVelt } from '@veltdev/client';
>
> const client = await initVelt('YOUR_API_KEY');
>
> // Set the document scope
> client.setDocument('my-document-id', { documentName: 'My Document' });
>
> // Authenticate a user
> await client.identify({
>   userId: 'user-1',
>   name: 'John Doe',
>   email: 'john@example.com',
> });
>
> // Wait for the SDK to be ready
> client.getVeltInitState().subscribe((isReady) => {
>   if (isReady) {
>     initializeStore(client);
>   }
> });
> ```

### 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:

> [card] [Array Store](https://velt.dev/docs/realtime-collaboration/crdt/setup/core-stores/array.md)
>
> Collaborative ordered lists — todo apps, item collections, ordered datasets.

> [card] [Map Store](https://velt.dev/docs/realtime-collaboration/crdt/setup/core-stores/map.md)
>
> Collaborative key-value pairs — settings, metadata, configuration objects.

> [card] [Text Store](https://velt.dev/docs/realtime-collaboration/crdt/setup/core-stores/text.md)
>
> Collaborative plain text — notepads, code editors, text fields.

> [card] [XML Store](https://velt.dev/docs/realtime-collaboration/crdt/setup/core-stores/xml.md)
>
> Collaborative XML/tree data — outlines, structured documents, custom tree editors.

### Step 4: Event subscriptions (optional)

> [tab] React / Next.js
>
> Use the `useCrdtEventCallback` hook to listen for CRDT events:
>
> ```jsx theme={null}
> import { useCrdtEventCallback } from '@veltdev/react';
>
> function YourComponent() {
>   const updateDataEvent = useCrdtEventCallback('updateData');
>
>   useEffect(() => {
>     if (updateDataEvent) {
>       console.log('CRDT data updated:', updateDataEvent);
>     }
>   }, [updateDataEvent]);
> }
> ```

> [tab] Other Frameworks
>
> Use `getCrdtElement().on()` to listen for CRDT events like `updateData`, which fires whenever the store data is synced.
>
> ```js theme={null}
> const crdtElement = client.getCrdtElement();
>
> crdtElement.on('updateData').subscribe((event) => {
>   if (event) {
>     console.log('CRDT data updated:', event);
>   }
> });
> ```

### Step 5: Custom encryption (optional)

> [tab] React / Next.js
>
> Pass a custom `VeltEncryptionProvider` to `VeltProvider` to encrypt/decrypt CRDT state before it is stored on the backend.
>
> ```tsx theme={null}
> import { VeltProvider } from '@veltdev/react';
> import { VeltEncryptionProvider } from '@veltdev/types';
>
> const encryptionProvider: VeltEncryptionProvider<number[], string> = {
>   encrypt: async (config) => {
>     return config.data.map((num) => num.toString()).join('__');
>   },
>   decrypt: async (config) => {
>     return config.data.split('__').map((str) => parseInt(str, 10));
>   },
> };
>
> function App() {
>   return (
>     <VeltProvider apiKey="YOUR_API_KEY" encryptionProvider={encryptionProvider}>
>       <YourAppContent />
>     </VeltProvider>
>   );
> }
> ```

> [tab] Other Frameworks
>
> Call `client.setEncryptionProvider()` to encrypt/decrypt CRDT state before it is stored on the backend.
>
> ```js theme={null}
> const encryptionProvider = {
>   encrypt: async (config) => {
>     return config.data.map((num) => num.toString()).join('__');
>   },
>   decrypt: async (config) => {
>     return config.data.split('__').map((str) => parseInt(str, 10));
>   },
> };
>
> client.setEncryptionProvider(encryptionProvider);
> ```

See also: [setEncryptionProvider()](https://velt.dev/docs/api-reference/sdk/api/api-methods.md#setencryptionprovider-encryptionprovider)
· [VeltEncryptionProvider](https://velt.dev/docs/api-reference/sdk/models/data-models.md#veltencryptionprovider)
· [EncryptConfig](https://velt.dev/docs/api-reference/sdk/models/data-models.md#encryptconfig)
· [DecryptConfig](https://velt.dev/docs/api-reference/sdk/models/data-models.md#decryptconfig)

## 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`: If `true`, always reset to `initialValue` on init. Default: `false`.
  * `onError`: Error callback.
  * `veltClient`: Explicit Velt client. Falls back to `VeltProvider` context.
* Returns: `UseStoreReturn<T>`
  * `value`: Current store value, reactively updated.
  * `update`: Replace the entire store value.
  * `store`: Underlying store instance for advanced use.
  * `isLoading`: `true` while the store is initializing.
  * `isSynced`: `true` when 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.

```tsx theme={null}
import { useStore } from '@veltdev/crdt-react';

const {
  value,
  update,
  store,
  isLoading,
  isSynced,
  status,
  error,
  saveVersion,
  getVersions,
  getVersionById,
  restoreVersion,
  setStateFromVersion,
} = useStore<Item[]>({
  storeId: 'my-array-store',
  type: 'array', // can be 'array', 'map', 'text', 'xml', or 'xmltext'
  initialValue: [],
});
```

### 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 from `useStore()` (safe to pass `null`)
* Returns: `UseAwarenessReturn<T>`
  * `remoteStates`: Awareness states of all remote peers.
  * `localState`: Current local awareness state.
  * `setLocalState`: Set or clear the local awareness state.

```tsx theme={null}
import { useStore, useAwareness } from '@veltdev/crdt-react';

const { store } = useStore<Item[]>({ storeId: 'my-store', type: 'array', initialValue: [] });
const { remoteStates, localState, setLocalState } = useAwareness(store);

setLocalState({
  user: { userId: 'user-1', name: 'John', color: '#ff0000' },
  cursor: { anchor: 0, head: 5 },
});
```

### Non-React: createVeltStore()

Convenience factory that creates a `Store`, calls `initialize()`, and returns it. Returns `null` if initialization fails.

* Params: [StoreConfig](https://velt.dev/docs/api-reference/sdk/models/data-models.md#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 (from `initVelt()`). Required for sync.
  * `debounceMs`: Throttle interval (ms) for backend writes. Default: `0`.
  * `enablePresence`: Enable presence tracking. Default: `true`.
  * `forceResetInitialContent`: If `true`, always reset to `initialValue` on 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>`

```js theme={null}
const store = await createVeltStore({
  id: 'my-array-store',
  type: 'array',
  initialValue: [{ id: '1', name: 'First item' }],
  veltClient: client,
});
```

### Store Methods

These methods are available on the `store` instance (from `useStore` or `createVeltStore`):

#### update()

Update the store value and sync to peers.

* Params: `newValue: T`
* Returns: `void`

```ts theme={null}
store.update('New Value');
```

#### getValue()

Get the current store value. For map stores, returns the `toJSON()` representation of the underlying Y.Map as a plain JavaScript object.

* Returns: `T`

```ts theme={null}
const value = store.getValue();
```

#### subscribe()

Subscribe to changes in the store.

* Params: `(newValue: T) => void`
* Returns: `() => void` (unsubscribe function)

```ts theme={null}
const unsubscribe = store.subscribe((newValue) => {
  console.log('Updated value:', newValue);
});
```

#### destroy()

Clean up resources when done with the store. Automatic in React via the hook.

* Returns: `void`

```ts theme={null}
store.destroy();
```

#### getDoc()

Get the underlying Yjs document.

* Returns: `Y.Doc`

```ts theme={null}
const ydoc = store.getDoc();
```

#### getProvider()

Get the provider instance for the store.

* Returns: `Provider`

```ts theme={null}
const provider = store.getProvider();
```

#### getText()

Get the Y.Text instance if store type is 'text'.

* Returns: `Y.Text | null`

```ts theme={null}
const ytext = store.getText();
```

#### getXml()

Get the Y.XmlFragment instance if store type is 'xml'.

* Returns: `Y.XmlFragment | null`

```ts theme={null}
const yxml = store.getXml();
```

#### getAwareness()

Get the Awareness instance for cursor/presence tracking.

* Returns: `Awareness`

```ts theme={null}
const awareness = store.getAwareness();
```

### Version Methods

Available on both the `useStore` hook return and the `store` instance:

#### saveVersion()

Save a snapshot of the current state as a named version.

* Params: `versionName: string`
* Returns: `Promise<string>`

```ts theme={null}
const versionId = await saveVersion('Checkpoint');
```

#### getVersions()

Fetch all saved versions.

* Returns: `Promise<Version[]>`

```ts theme={null}
const versions = await getVersions();
```

#### getVersionById()

Fetch a specific version by ID.

* Params: `versionId: string`
* Returns: `Promise<Version | null>`

```ts theme={null}
const version = await getVersionById('abc123');
```

#### restoreVersion()

Restore the store to a specific version using its ID.

* Params: `versionId: string`
* Returns: `Promise<boolean>`

```ts theme={null}
await restoreVersion('abc123');
```

#### setStateFromVersion()

Restore the store state from a specific version object.

* Params: `version: Version`
* Returns: `Promise<void>`

```ts theme={null}
await setStateFromVersion(version);
```

### Custom Encryption

Encrypt CRDT data before it's stored in Velt by registering a custom encryption provider. For CRDT methods, input data is of type `Uint8Array | number[]`.

> [tab] React / Next.js
>
> ```tsx theme={null}
> import { VeltProvider } from '@veltdev/react';
> import { VeltEncryptionProvider } from '@veltdev/types';
>
> const encryptionProvider: VeltEncryptionProvider<number[], string> = {
>   encrypt: async (config) => {
>     return config.data.map((num) => num.toString()).join('__');
>   },
>   decrypt: async (config) => {
>     return config.data.split('__').map((str) => parseInt(str, 10));
>   },
> };
>
> function App() {
>   return (
>     <VeltProvider apiKey="YOUR_API_KEY" encryptionProvider={encryptionProvider}>
>       <YourAppContent />
>     </VeltProvider>
>   );
> }
> ```

> [tab] Other Frameworks
>
> ```js theme={null}
> const encryptionProvider = {
>   encrypt: async (config) => {
>     return config.data.map((num) => num.toString()).join('__');
>   },
>   decrypt: async (config) => {
>     return config.data.split('__').map((str) => parseInt(str, 10));
>   },
> };
>
> client.setEncryptionProvider(encryptionProvider);
> ```

See also: [setEncryptionProvider()](https://velt.dev/docs/api-reference/sdk/api/api-methods.md#setencryptionprovider-encryptionprovider)
· [VeltEncryptionProvider](https://velt.dev/docs/api-reference/sdk/models/data-models.md#veltencryptionprovider)
· [EncryptConfig](https://velt.dev/docs/api-reference/sdk/models/data-models.md#encryptconfig)
· [DecryptConfig](https://velt.dev/docs/api-reference/sdk/models/data-models.md#decryptconfig)

### CRDT Event Subscriptions

#### [on](https://velt.dev/docs/api-reference/sdk/api/api-methods.md#on)

Subscribe to CRDT events. Currently supports the `updateData` event which fires when CRDT data changes.

* Params: `eventType: "updateData"`
* Returns: `Observable<`[`CrdtUpdateDataEvent`](https://velt.dev/docs/api-reference/sdk/models/data-models#crdtupdatedataevent)`>`

> [tab] React / Next.js
>
> **Using Hook:**
>
> ```jsx theme={null}
> import { useCrdtEventCallback } from "@veltdev/react";
>
> export function YourComponent() {
>   const crdtUpdateData = useCrdtEventCallback("updateData");
>
>   useEffect(() => {
>     console.log("[CRDT] event on data change: ", crdtUpdateData);
>   }, [crdtUpdateData]);
>
>   return <div>Your Component</div>;
> }
> ```
>
> **Using API:**
>
> ```jsx theme={null}
> import { useVeltClient } from "@veltdev/react";
>
> export function YourComponent() {
>   const { client } = useVeltClient();
>
>   useEffect(() => {
>     if (!client) return;
>     const crdtElement = client.getCrdtElement();
>     const subscription = crdtElement.on("updateData").subscribe((eventData) => {
>       console.log("[CRDT] event on data change: ", eventData);
>     });
>     return () => subscription.unsubscribe();
>   }, [client]);
>
>   return <div>Your Component</div>;
> }
> ```

> [tab] Other Frameworks
>
> ```html theme={null}
> <script>
> const crdtElement = Velt.getCrdtElement();
>
> crdtElement.on("updateData").subscribe((eventData) => {
>   console.log("[CRDT] event on data change: ", eventData);
> });
> </script>
> ```

### Low-Level Message APIs

These APIs provide direct access to the CRDT message stream for custom implementations.

#### [pushMessage()](https://velt.dev/docs/api-reference/sdk/api/api-methods.md#pushmessage)

Push a raw Yjs message into the unified message stream.

* Params: [`CrdtPushMessageQuery`](https://velt.dev/docs/api-reference/sdk/models/data-models#crdtpushmessagequery)
* Returns: `Promise<void>`

> [tab] React / Next.js
>
> ```jsx theme={null}
> const crdtElement = client.getCrdtElement();
>
> await crdtElement.pushMessage({
>   id: 'my-doc',
>   data: Array.from(update),
>   yjsClientId: ydoc.clientID,
>   messageType: 'sync',
>   source: 'tiptap',
> });
> ```

> [tab] Other Frameworks
>
> ```js theme={null}
> const crdtElement = Velt.getCrdtElement();
>
> await crdtElement.pushMessage({
>   id: 'my-doc',
>   data: Array.from(update),
>   yjsClientId: ydoc.clientID,
>   messageType: 'sync',
>   source: 'tiptap',
> });
> ```

#### [onMessage()](https://velt.dev/docs/api-reference/sdk/api/api-methods.md#onmessage)

Subscribe to incoming messages on the unified message stream. Returns an unsubscribe function.

* Params: [`CrdtOnMessageQuery`](https://velt.dev/docs/api-reference/sdk/models/data-models#crdtonmessagequery)
* Returns: `() => void`

> [tab] React / Next.js
>
> ```jsx theme={null}
> const crdtElement = client.getCrdtElement();
>
> const unsubscribe = crdtElement.onMessage({
>   id: 'my-doc',
>   callback: (msg) => {
>     Y.applyUpdate(ydoc, new Uint8Array(msg.data));
>   },
> });
>
> unsubscribe();
> ```

> [tab] Other Frameworks
>
> ```js theme={null}
> const crdtElement = Velt.getCrdtElement();
>
> const unsubscribe = crdtElement.onMessage({
>   id: 'my-doc',
>   callback: (msg) => {
>     Y.applyUpdate(ydoc, new Uint8Array(msg.data));
>   },
> });
>
> unsubscribe();
> ```

#### [getMessages()](https://velt.dev/docs/api-reference/sdk/api/api-methods.md#getmessages)

Retrieve historical messages from the unified message stream.

* Params: [`CrdtGetMessagesQuery`](https://velt.dev/docs/api-reference/sdk/models/data-models#crdtgetmessagesquery)
* Returns: [`Promise<CrdtMessageData[]>`](https://velt.dev/docs/api-reference/sdk/models/data-models#crdtmessagedata)

> [tab] React / Next.js
>
> ```jsx theme={null}
> const crdtElement = client.getCrdtElement();
>
> const messages = await crdtElement.getMessages({
>   id: 'my-doc',
>   afterTs: snapshot?.timestamp ?? 0,
> });
> for (const msg of messages) {
>   Y.applyUpdate(ydoc, new Uint8Array(msg.data));
> }
> ```

> [tab] Other Frameworks
>
> ```js theme={null}
> const crdtElement = Velt.getCrdtElement();
>
> const messages = await crdtElement.getMessages({
>   id: 'my-doc',
>   afterTs: snapshot?.timestamp ?? 0,
> });
> for (const msg of messages) {
>   Y.applyUpdate(ydoc, new Uint8Array(msg.data));
> }
> ```

#### [getSnapshot()](https://velt.dev/docs/api-reference/sdk/api/api-methods.md#getsnapshot)

Retrieve the latest CRDT state snapshot for a document.

* Params: [`CrdtGetSnapshotQuery`](https://velt.dev/docs/api-reference/sdk/models/data-models#crdtgetsnapshotquery)
* Returns: [`Promise<CrdtSnapshotData | null>`](https://velt.dev/docs/api-reference/sdk/models/data-models#crdtsnapshotdata)

> [tab] React / Next.js
>
> ```jsx theme={null}
> const crdtElement = client.getCrdtElement();
>
> const snapshot = await crdtElement.getSnapshot({ id: 'my-doc' });
> if (snapshot?.state) {
>   Y.applyUpdate(ydoc, new Uint8Array(snapshot.state));
> }
> ```

> [tab] Other Frameworks
>
> ```js theme={null}
> const crdtElement = Velt.getCrdtElement();
>
> const snapshot = await crdtElement.getSnapshot({ id: 'my-doc' });
> if (snapshot?.state) {
>   Y.applyUpdate(ydoc, new Uint8Array(snapshot.state));
> }
> ```

#### [saveSnapshot()](https://velt.dev/docs/api-reference/sdk/api/api-methods.md#savesnapshot)

Persist a CRDT state snapshot for a document.

* Params: [`CrdtSaveSnapshotQuery`](https://velt.dev/docs/api-reference/sdk/models/data-models#crdtsavesnapshotquery)
* Returns: `Promise<void>`

> [tab] React / Next.js
>
> ```jsx theme={null}
> const crdtElement = client.getCrdtElement();
>
> await crdtElement.saveSnapshot({
>   id: 'my-doc',
>   state: Y.encodeStateAsUpdate(ydoc),
>   vector: Y.encodeStateVector(ydoc),
>   source: 'tiptap',
> });
> ```

> [tab] Other Frameworks
>
> ```js theme={null}
> const crdtElement = Velt.getCrdtElement();
>
> await crdtElement.saveSnapshot({
>   id: 'my-doc',
>   state: Y.encodeStateAsUpdate(ydoc),
>   vector: Y.encodeStateVector(ydoc),
>   source: 'tiptap',
> });
> ```

#### [pruneMessages()](https://velt.dev/docs/api-reference/sdk/api/api-methods.md#prunemessages)

Delete historical messages older than a given timestamp from the message stream.

* Params: [`CrdtPruneMessagesQuery`](https://velt.dev/docs/api-reference/sdk/models/data-models#crdtprunemessagesquery)
* Returns: `Promise<void>`

> [tab] React / Next.js
>
> ```jsx theme={null}
> const crdtElement = client.getCrdtElement();
>
> await crdtElement.pruneMessages({
>   id: 'my-doc',
>   beforeTs: Date.now() - 24 * 60 * 60 * 1000,
> });
> ```

> [tab] Other Frameworks
>
> ```js theme={null}
> const crdtElement = Velt.getCrdtElement();
>
> await crdtElement.pruneMessages({
>   id: 'my-doc',
>   beforeTs: Date.now() - 24 * 60 * 60 * 1000,
> });
> ```

## Migration Guide: v1 to v2

### React

#### Overview

The v2 API replaces `useVeltCrdtStore()` 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:**

```tsx theme={null}
// Before (v1)
import { useVeltCrdtStore } from '@veltdev/crdt-react';
const { value, update, store } = useVeltCrdtStore<string>({ id: 'my-doc', type: 'text' });

// After (v2)
import { useStore } from '@veltdev/crdt-react';
const { value, update, store, isLoading, isSynced, status, error } = useStore<string>({
  storeId: 'my-doc',
  type: 'text',
  onError: (err) => console.error(err),
});
```

**2. Add status monitoring (new in v2):**

```tsx theme={null}
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
```

## Legacy API (v1)

> [!WARNING]
>
> The v1 `useVeltCrdtStore` hook is deprecated. Use the v2 `useStore` hook for all new React integrations. The non-React `createVeltStore` API remains unchanged.

### useVeltCrdtStore() (deprecated)

React hook to create and sync a collaborative CRDT store. Internally delegates to `useStore` (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`)

```jsx theme={null}
import { useVeltCrdtStore } from '@veltdev/crdt-react';

const {
  value,
  versions,
  store,
  update,
  saveVersion,
  getVersions,
  getVersionById,
  restoreVersion,
  setStateFromVersion,
} = useVeltCrdtStore<string>({
  id: 'my-collab-note',
  type: 'text',
  initialValue: 'Hello, world!',
});
```

## Debugging

Use the Velt Chrome Extension or the `window.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()](https://velt.dev/docs/api-reference/sdk/api/api-methods.md#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 store
    * `subscribe(callback: (value: any) => void)`: Subscribe to changes. Returns an unsubscribe function.

> [tab] Basic Usage
>
> ```jsx theme={null}
> // Get a specific store
> const store = window.VeltCrdtStoreMap.get('my-store-id');
> if (store) {
>   console.log('Current value:', store.getValue());
> }
>
> // Get the first registered store
> const firstStore = window.VeltCrdtStoreMap.get();
> ```

> [tab] Inspect Store
>
> ```jsx theme={null}
> const store = window.VeltCrdtStoreMap.get('editor-123');
>
> if (store) {
>   console.log('Current value:', store.getValue());
>
>   store.subscribe((value) => {
>     console.log('Value updated:', value);
>   });
>
>   setInterval(() => {
>     console.log('Current value:', store.getValue());
>   }, 5000);
> }
> ```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.