Skip to content

Modes

View as Markdown

A mode is a named set of Storybook globals (theme, locale, backgrounds, …) and an optional viewport. Every story is captured once per mode, and each mode keeps its own baseline and approval.

Modes live in story parameters, at project, component or story level. Levels stack, so a story captures every mode declared above it. Both parameter keys work and are merged per mode name; storyshelf wins over chromatic for the same name.

// .storybook/preview.ts — every story
export default {
parameters: {
chromatic: {
modes: {
light: { theme: "light" },
dark: { theme: "dark" },
},
},
},
};
// Button.stories.ts — this component adds a narrow viewport
export default {
parameters: {
storyshelf: { modes: { mobile: { viewport: "mobile1", theme: "dark" } } },
},
};

A mode value is:

KeyMeaning
viewportA width in px, a Storybook viewport name (mobile1, tablet, or one from parameters.viewport.viewports), or { width, height }. Omitted: the project’s first viewport.
disable: trueSkip an inherited mode (or viewport of the same name) for this story.
anything elseA Storybook global, passed on the iframe URL as globals=…. Nested objects flatten (backgrounds: { value: "#fff" } → backgrounds.value:!hex(fff)).

A mode’s baseline is keyed by the slug of its name (Dark Desktop → dark-desktop), not its values. Changing what a mode does keeps comparing against the same baseline; renaming it creates a new one, like renaming a story. A mode named like a project viewport (for example desktop) replaces that viewport’s capture.

  • At most 8 captures per story (project viewports + default viewport + modes). A story over the cap fails the build before anything renders.
  • modesAllowlist on the project (a JSON list of mode names) restricts which declared modes run. Unset runs all of them.
  • The Playwright runner reads modes from the running preview, so project-level and component-level modes are picked up without any index parameters. The Puppeteer runner only sees parameters present in index.json.

Modes combine with the project’s browsers list: each story × mode is captured on every listed engine, one engine at a time, and each engine keeps its own baseline. Engines are never compared with each other.