# How to Use Storybook Manager API Stores (Status, Test-Provider, Checklist)

> Learn to use Storybook Manager API stores like status testprovider and checklist to read and mutate UI state with experimental hooks and internal store instances

- Repository: [Storybook/storybook](https://github.com/storybookjs/storybook)
- Tags: how-to-guide
- Published: 2026-02-27

---

**The Storybook Manager API exposes three reactive stores—status, test-provider, and checklist—that allow addons to read and mutate the manager UI state using experimental hooks and internal store instances.**

The `@storybook/manager-api` package provides direct access to Storybook's internal state through specialized stores built on a universal store infrastructure. These stores manage the runtime status of stories, test provider states, and checklist widget items, enabling addons to synchronize with the manager UI.

## Understanding the Three Core Stores

Each store is created in its respective file under `code/core/src/manager-api/stores/` and follows a consistent architecture: a universal store holds the raw state, while a domain-specific API provides convenient methods for interaction.

### Status Store

The **status store** tracks the runtime state of individual stories (e.g., `pending`, `running`, `error`). According to the source code in [`code/core/src/manager-api/stores/status.ts`](https://github.com/storybookjs/storybook/blob/main/code/core/src/manager-api/stores/status.ts), the store is created via `createStatusStore` using a universal store instance.

Key exports include:
- `fullStatusStore` – the complete status store instance
- `getStatusStoreByTypeId` – retrieves a typed subset of the store
- `useStatusStore` – React hook for reactive subscriptions
- `universalStatusStore` – the underlying universal store (exposed as `internal_universalStatusStore`)

### Test-Provider Store

The **test-provider store** manages the state of test runners such as Vitest or Jest. Defined in [`code/core/src/manager-api/stores/test-provider.ts`](https://github.com/storybookjs/storybook/blob/main/code/core/src/manager-api/stores/test-provider.ts), this store tracks whether providers are running, crashed, or pending per provider ID.

Key exports include:
- `fullTestProviderStore` – the main store instance
- `getTestProviderStoreById` – accessor for specific provider IDs
- `useTestProviderStore` – React hook for components
- `universalTestProviderStore` – underlying universal store (exposed as `internal_universalTestProviderStore`)

### Checklist Store

The **checklist store** controls the "Checklist" widget items displayed in the sidebar, handling accept/done/skip actions. Implemented in [`code/core/src/manager-api/stores/checklist.ts`](https://github.com/storybookjs/storybook/blob/main/code/core/src/manager-api/stores/checklist.ts) via `createChecklistStore`, this store provides a simpler API focused on item manipulation.

Key exports include:
- `checklistStore` – the primary store instance (exposed as `internal_checklistStore`)
- `universalChecklistStore` – the universal store backing (exposed as `internal_universalChecklistStore`)
- `useChecklistStore` – React hook for UI components (consumed by [`ChecklistWidget.tsx`](https://github.com/storybookjs/storybook/blob/main/ChecklistWidget.tsx))

## Accessing Stores in Your Addon

The manager API exposes two patterns for store access: experimental hooks for React components and direct store instances for imperative operations.

### Using Experimental Hooks

For read-only access within React components, use the experimental hooks exported from [`code/core/src/manager-api/index.ts`](https://github.com/storybookjs/storybook/blob/main/code/core/src/manager-api/index.ts):

```typescript
import { 
  experimental_useStatusStore,
  experimental_useTestProviderStore 
} from '@storybook/manager-api';

function MyPanel() {
  const statusStore = experimental_useStatusStore();
  const testProviderStore = experimental_useTestProviderStore(id => id['my-addon']);
  
  // Use store methods...
}

```

### Using Store Instances

To mutate state or access stores outside React, import the internal store instances or use the experimental getter functions:

```typescript
import { 
  internal_fullStatusStore,
  experimental_getTestProviderStore 
} from '@storybook/manager-api';

// Direct access to status store
const allStatuses = internal_fullStatusStore.getAll();

// Get specific test provider store
const vitestStore = experimental_getTestProviderStore('vitest');
await vitestStore.setState('test-provider-state:running');

```

## Practical Code Examples

### Reading Story Status Changes

Subscribe to status updates to react to story state changes in real-time. This example uses the status store from [`code/core/src/manager-api/stores/status.ts`](https://github.com/storybookjs/storybook/blob/main/code/core/src/manager-api/stores/status.ts):

```typescript
import { experimental_useStatusStore } from '@storybook/manager-api';
import { useEffect } from 'react';

function StoryStatusMonitor() {
  const { getAll, onAllStatusChange } = experimental_useStatusStore();

  useEffect(() => {
    return onAllStatusChange((newStatuses, prevStatuses) => {
      console.log('Status updated:', { newStatuses, prevStatuses });
    });
  }, [onAllStatusChange]);

  const currentStatuses = getAll();
  return (
    <ul>
      {currentStatuses.map(status => (
        <li key={status.storyId}>
          {status.storyId}: {status.status}
        </li>
      ))}
    </ul>
  );
}

```

### Updating Test Provider State

Control test runner states programmatically using the test-provider store defined in [`code/core/src/manager-api/stores/test-provider.ts`](https://github.com/storybookjs/storybook/blob/main/code/core/src/manager-api/stores/test-provider.ts):

```typescript
import {
  experimental_getTestProviderStore,
  experimental_useTestProviderStore,
} from '@storybook/manager-api';

const PROVIDER_ID = 'my-addon/vitest';

// Imperative state updates
const providerStore = experimental_getTestProviderStore(PROVIDER_ID);
await providerStore.setState('test-provider-state:running');

// Later, mark as crashed
await providerStore.setState('test-provider-state:crashed');

// Reactive component integration
function ProviderStatusBadge() {
  const { state } = experimental_useTestProviderStore(id => id[PROVIDER_ID]);
  return <div>Current state: {state}</div>;
}

```

### Manipulating Checklist Items

Interact with the checklist widget using the store from [`code/core/src/manager-api/stores/checklist.ts`](https://github.com/storybookjs/storybook/blob/main/code/core/src/manager-api/stores/checklist.ts):

```typescript
import { internal_checklistStore, useChecklistStore } from '@storybook/manager-api';

// Programmatic item management
internal_checklistStore.accept('item-id-123');
internal_checklistStore.done('item-id-123');
internal_checklistStore.skip('item-id-456');

// React component implementation
function ChecklistPanel() {
  const { items, accept, done, skip } = useChecklistStore();
  
  return (
    <ul>
      {items.map(item => (
        <li key={item.id}>
          {item.title}
          <button onClick={() => accept(item.id)}>Accept</button>
          <button onClick={() => done(item.id)}>Done</button>
          <button onClick={() => skip(item.id)}>Skip</button>
        </li>
      ))}
    </ul>
  );
}

```

## Summary

- **Storybook Manager API stores** provide reactive state management for the manager UI through three specialized stores: status, test-provider, and checklist.
- **Universal store infrastructure** powers each implementation, with domain-specific wrappers exposing methods like `setState`, `getAll`, and `onAllStatusChange`.
- **Experimental hooks** (`experimental_useStatusStore`, `experimental_useTestProviderStore`) offer reactive access for React components, while **internal store instances** enable imperative state mutations from addons.
- **Source locations**: Store definitions reside in `code/core/src/manager-api/stores/` (status.ts, test-provider.ts, checklist.ts), with shared implementations in `code/core/src/shared/`.

## Frequently Asked Questions

### What is the difference between experimental hooks and internal store instances?

**Experimental hooks** like `experimental_useStatusStore` are designed for React components to subscribe to state changes reactively. **Internal store instances** such as `internal_fullStatusStore` provide direct imperative access to the underlying universal store, allowing you to mutate state or read values outside of React components. Use hooks for UI rendering and internal instances for addon logic or programmatic updates.

### Can I use these stores outside of React components?

Yes, you can access stores outside React by importing the **internal store instances** or using the **experimental getter functions**. For example, import `internal_checklistStore` to call `accept()` or `done()` directly, or use `experimental_getTestProviderStore('provider-id')` to retrieve a specific store instance for imperative state updates.

### How do I subscribe to specific status changes rather than all changes?

While `onAllStatusChange` provides updates for every status change, you can filter within the callback or use the `select` method available on the status store to query specific story IDs or types. The store exposes methods like `getAll()` which returns an array you can filter, or you can use `getStatusStoreByTypeId` to scope your subscription to a specific status type.

### Are these stores available in all Storybook versions?

The Manager API stores are available in **Storybook 8.0 and later**, where the manager API was consolidated into the core package structure. The experimental exports (`experimental_useStatusStore`, etc.) and internal store instances represent the current stable API as implemented in the `next` branch. If you are using an older version, you may need to upgrade to access these specific store implementations.