---
sidebar_position: 10
---

# Storage API

Plugins can store local client data and per-server data. Desktop builds use Electron persistence when available; browser fallback uses renderer storage.

## Required Capabilities

| Method | Capability |
| --- | --- |
| `clientData.read(key)` | `storage.local` |
| `clientData.write(key, value)` | `storage.local` |
| `clientData.remove(key)` | `storage.local` |
| `serverData.read(key)` | `storage.serverData.read` |
| `serverData.write(key, value)` | `storage.serverData.write` |
| `serverData.remove(key)` | `storage.serverData.write` |
| `storage.get(key)` | `storage.local` |
| `storage.set(key, value)` | `storage.local` |
| `storage.remove(key)` | `storage.local` |

## Client Data

Client data belongs to this local user and client.

```js
export async function activate(context) {
  await context.api.clientData.write('soundboard:volume', {
    masterVolume: 0.7,
    updatedAt: 1777473600000
  });

  const value = await context.api.clientData.read('soundboard:volume');

  context.api.logger.info('Loaded client data', value);
}
```

## Server Data

Server data is local per-user/per-server state. It is not arbitrary signal-server persistence.

```js
export async function activate(context) {
  await context.api.serverData.write('soundboard:favorites', [
    { id: 'chime', label: 'Chime', url: 'https://cdn.example.com/chime.wav' },
    { id: 'ready', label: 'Ready Check', url: 'https://cdn.example.com/ready.wav' }
  ]);

  const favorites = await context.api.serverData.read('soundboard:favorites');

  context.api.logger.info('Loaded server favorites', favorites);
}
```

## Remove Data

```js
export async function activate(context) {
  await context.api.clientData.remove('soundboard:volume');
  await context.api.serverData.remove('soundboard:favorites');
}
```

## Legacy Synchronous Storage

The `storage.*` methods are legacy local storage helpers. Prefer `clientData.*` for new plugins when async reads are acceptable.

```js
export function activate(context) {
  context.api.storage.set('quick-toggle', { enabled: true });

  const saved = context.api.storage.get('quick-toggle');

  context.api.logger.info('Legacy storage value', saved);

  context.api.storage.remove('quick-toggle');
}
```

## Manifest Data Declarations

Declare important data keys in the manifest.

```json
{
  "data": [
    {
      "key": "soundboard:volume",
      "scope": "client",
      "storage": "local"
    },
    {
      "key": "soundboard:favorites",
      "scope": "server",
      "storage": "serverData"
    }
  ]
}
```