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

<Tabs>
  <Tab title="React / Next.js">
    ```bash theme={null}
    npm install @veltdev/crdt-react @veltdev/crdt @veltdev/react
    ```
  </Tab>

  <Tab title="Other Frameworks">
    ```bash theme={null}
    npm install @veltdev/crdt @veltdev/client
    ```
  </Tab>
</Tabs>

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

<Tabs>
  <Tab title="React / Next.js">
    Wrap your app with `VeltProvider` and use `useSetDocument` to scope the collaborative session. Follow the [Velt Setup Docs](/get-started/quickstart) 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>

  <Tab title="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);
      }
    });
    ```
  </Tab>
</Tabs>

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

<CardGroup cols={2}>
  <Card title="Array Store" icon="list" href="/realtime-collaboration/crdt/setup/core-stores/array">
    Collaborative ordered lists — todo apps, item collections, ordered datasets.
  </Card>

  <Card title="Map Store" icon="key" href="/realtime-collaboration/crdt/setup/core-stores/map">
    Collaborative key-value pairs — settings, metadata, configuration objects.
  </Card>

  <Card title="Text Store" icon="text" href="/realtime-collaboration/crdt/setup/core-stores/text">
    Collaborative plain text — notepads, code editors, text fields.
  </Card>

  <Card title="XML Store" icon="code" href="/realtime-collaboration/crdt/setup/core-stores/xml">
    Collaborative XML/tree data — outlines, structured documents, custom tree editors.
  </Card>
</CardGroup>

### Step 4: Event subscriptions (optional)

<Tabs>
  <Tab title="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>

  <Tab title="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);
      }
    });
    ```
  </Tab>
</Tabs>

### Step 5: Custom encryption (optional)

<Tabs>
  <Tab title="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>

  <Tab title="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);
    ```
  </Tab>
</Tabs>

See also: [setEncryptionProvider()](/api-reference/sdk/api/api-methods#setencryptionprovider-encryptionprovider)
· [VeltEncryptionProvider](/api-reference/sdk/models/data-models#veltencryptionprovider)
· [EncryptConfig](/api-reference/sdk/models/data-models#encryptconfig)
· [DecryptConfig](/api-reference/sdk/models/data-models#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](/api-reference/sdk/models/data-models#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[]`.

<Tabs>
  <Tab title="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>

  <Tab title="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);
    ```
  </Tab>
</Tabs>

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

### CRDT Event Subscriptions

#### [on](/api-reference/sdk/api/api-methods#on)

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

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

<Tabs>
  <Tab title="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>

  <Tab title="Other Frameworks">
    ```html theme={null}
    <script>
    const crdtElement = Velt.getCrdtElement();

    crdtElement.on("updateData").subscribe((eventData) => {
      console.log("[CRDT] event on data change: ", eventData);
    });
    </script>
    ```
  </Tab>
</Tabs>

### Low-Level Message APIs

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

#### [pushMessage()](/api-reference/sdk/api/api-methods#pushmessage)

Push a raw Yjs message into the unified message stream.

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

<Tabs>
  <Tab title="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>

  <Tab title="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',
    });
    ```
  </Tab>
</Tabs>

#### [onMessage()](/api-reference/sdk/api/api-methods#onmessage)

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

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

<Tabs>
  <Tab title="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>

  <Tab title="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();
    ```
  </Tab>
</Tabs>

#### [getMessages()](/api-reference/sdk/api/api-methods#getmessages)

Retrieve historical messages from the unified message stream.

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

<Tabs>
  <Tab title="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>

  <Tab title="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));
    }
    ```
  </Tab>
</Tabs>

#### [getSnapshot()](/api-reference/sdk/api/api-methods#getsnapshot)

Retrieve the latest CRDT state snapshot for a document.

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

<Tabs>
  <Tab title="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>

  <Tab title="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));
    }
    ```
  </Tab>
</Tabs>

#### [saveSnapshot()](/api-reference/sdk/api/api-methods#savesnapshot)

Persist a CRDT state snapshot for a document.

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

<Tabs>
  <Tab title="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>

  <Tab title="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',
    });
    ```
  </Tab>
</Tabs>

#### [pruneMessages()](/api-reference/sdk/api/api-methods#prunemessages)

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

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

<Tabs>
  <Tab title="React / Next.js">
    ```jsx theme={null}
    const crdtElement = client.getCrdtElement();

    await crdtElement.pruneMessages({
      id: 'my-doc',
      beforeTs: Date.now() - 24 * 60 * 60 * 1000,
    });
    ```
  </Tab>

  <Tab title="Other Frameworks">
    ```js theme={null}
    const crdtElement = Velt.getCrdtElement();

    await crdtElement.pruneMessages({
      id: 'my-doc',
      beforeTs: Date.now() - 24 * 60 * 60 * 1000,
    });
    ```
  </Tab>
</Tabs>

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

### 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()](/api-reference/sdk/api/api-methods#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.

<Tabs>
  <Tab title="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>

  <Tab title="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);
    }
    ```
  </Tab>
</Tabs>
