How to Use Storybook Manager API Stores (Status, Test-Provider, Checklist)
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, the store is created via createStatusStore using a universal store instance.
Key exports include:
fullStatusStore– the complete status store instancegetStatusStoreByTypeId– retrieves a typed subset of the storeuseStatusStore– React hook for reactive subscriptionsuniversalStatusStore– the underlying universal store (exposed asinternal_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, this store tracks whether providers are running, crashed, or pending per provider ID.
Key exports include:
fullTestProviderStore– the main store instancegetTestProviderStoreById– accessor for specific provider IDsuseTestProviderStore– React hook for componentsuniversalTestProviderStore– underlying universal store (exposed asinternal_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 via createChecklistStore, this store provides a simpler API focused on item manipulation.
Key exports include:
checklistStore– the primary store instance (exposed asinternal_checklistStore)universalChecklistStore– the universal store backing (exposed asinternal_universalChecklistStore)useChecklistStore– React hook for UI components (consumed byChecklistWidget.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:
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:
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:
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:
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:
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, andonAllStatusChange. - 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 incode/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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →