# @metamask/storage-service

> Platform-agnostic service for storing large, infrequently accessed controller data

Latest version **2.0.0** (published 2026-09-09) · (MIT OR Apache-2.0) license · 0 weekly downloads

## Install

```sh
npm install @metamask/storage-service
pnpm add @metamask/storage-service
yarn add @metamask/storage-service
bun add @metamask/storage-service
```

## Health

**Score 65/100 (B)** — status: active.

Positive: esm support; no vulnerabilities; has provenance; recently updated; high maintenance score.

Warnings: low downloads; no types.

## Facts

| | |
|---|---|
| Version | 2.0.0 |
| Published | 2026-09-09 |
| First published | 2025-12-11 |
| Weekly downloads | 0 |
| License | (MIT OR Apache-2.0) |
| TypeScript types | none |
| Module format | ESM |
| Node | ^22.14.0 \|\| ^24 |
| Dependencies | 2 |
| Unpacked size | 80.9 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 419 |
| Maintainers | frederikbolding, metamaskbot, gudahtt, mrten, mcmire, naugtur |
| Keywords | Ethereum, MetaMask |

## Links

- npm: https://www.npmjs.com/package/@metamask/storage-service
- Repository: https://github.com/MetaMask/core
- Homepage: https://github.com/MetaMask/core/tree/main/packages/storage-service#readme
- Issues: https://github.com/MetaMask/core/issues
- npm.io page: https://npm.io/package/@metamask/storage-service

## Dependencies (2)

- [@metamask/utils](https://npm.io/package/@metamask/utils.md) ^11.12.0
- [@metamask/messenger](https://npm.io/package/@metamask/messenger.md) ^3.0.0

## Recent versions

- 2.0.0 (latest) — 2026-09-09
- 1.0.2 — 2026-06-09
- 1.0.1 — 2026-03-26
- 1.0.0 — 2026-01-30
- 0.0.1 — 2025-12-11

## README

# `@metamask/storage-service`

A platform-agnostic service for storing large, infrequently accessed controller data outside of memory.

## When to Use

✅ **Use StorageService for:**

- Large data (> 100 KB)
- Infrequently accessed data
- Data that doesn't need to be in Redux state
- Examples: Snap source code, cached API responses

❌ **Don't use for:**

- Frequently accessed data (use controller state)
- Small data (< 10 KB - overhead not worth it)
- Data needed for UI rendering

## Installation

`yarn add @metamask/storage-service`

or

`npm install @metamask/storage-service`

## Usage

### Controller Setup

```typescript
import type {
  StorageServiceSetItemAction,
  StorageServiceGetItemAction,
} from '@metamask/storage-service';

// Grant access to storage actions
type AllowedActions =
  | StorageServiceSetItemAction
  | StorageServiceGetItemAction;

class MyController extends BaseController<...> {
  async storeData(id: string, data: string) {
    await this.messenger.call(
      'StorageService:setItem',
      'MyController',
      `${id}:data`,
      data,
    );
  }

  async getData(id: string): Promise<string | undefined> {
    const { result, error } = await this.messenger.call(
      'StorageService:getItem',
      'MyController',
      `${id}:data`,
    );
    if (error) {
      throw error;
    }
    // result is undefined if key doesn't exist
    return result as string | undefined;
  }
}
```

### Service Initialization

The service accepts an optional `StorageAdapter` for platform-specific storage:

```typescript
import { StorageService, type StorageAdapter } from '@metamask/storage-service';

// Production: Provide a platform-specific adapter
const service = new StorageService({
  messenger: storageServiceMessenger,
  storage: myPlatformAdapter, // FilesystemStorage, IndexedDB, etc.
});

// Testing: Uses in-memory storage by default
const testService = new StorageService({
  messenger: testMessenger,
  // No adapter needed - data isolated per test
});
```

### Events

Subscribe to storage changes:

```typescript
this.messenger.subscribe(
  'StorageService:itemSet:MyController',
  (key, value) => {
    console.log(`Data stored: ${key}`);
  },
);
```

## StorageAdapter Interface

Implement this interface to provide platform-specific storage:

```typescript
import type { Json } from '@metamask/utils';

// Response type for getItem - distinguishes found, not found, and error
type StorageGetResult =
  | { result: Json; error?: never } // Data found
  | { result?: never; error: Error } // Error occurred
  | Record<string, never>; // Key doesn't exist (empty object)

export type StorageAdapter = {
  getItem(namespace: string, key: string): Promise<StorageGetResult>;
  setItem(namespace: string, key: string, value: Json): Promise<void>;
  removeItem(namespace: string, key: string): Promise<void>;
  getAllKeys(namespace: string): Promise<string[]>;
  clear(namespace: string): Promise<void>;
};
```

Adapters are responsible for:

- Building the full storage key (e.g., `storageService:namespace:key`)
- Serializing/deserializing JSON data
- Returning the correct response format for getItem

## Contributing

This package is part of a monorepo. Instructions for contributing can be found in the [monorepo README](https://github.com/MetaMask/core#readme).

---
_Source: https://npm.io/package/@metamask/storage-service · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
