Test dark mode, themes, and viewports with modes
Capture a story in multiple viewports and themes with parameters.uiVerify.modes. Each mode gets its own baseline, and a Chromatic modes config carries over.
A mode is a capture variant of a story: a viewport and theme it should be screenshotted in. Declare modes on a story and UI Verify renders it once per mode, each diffed against its own per-mode baseline - so a single Button story can cover mobile light, desktop dark, and everything between, without a separate story for each.
How do I declare modes on a story?
Set parameters.uiVerify.modes to an object keyed by mode name, each entry giving a viewport and/or a theme. UI Verify reads the same shape under parameters.chromatic, the drop-in Chromatic-compatible namespace, so an existing Chromatic config carries over unchanged. Set it on a single story, or on the component meta to cover the whole file.
export default {
component: Button,
parameters: {
uiVerify: {
modes: {
"Mobile light": { viewport: "small", theme: "light" },
"Desktop dark": { viewport: "large", theme: "dark" },
},
},
},
};A mode's viewport is a named viewport from your Storybook viewport options. For plain widths with no theme, the legacy viewports array still works - parameters.uiVerify.viewports: [320, 768, 1280] renders the story at each pixel width.
Does each mode get its own baseline?
Yes. A story rendered in three modes produces three screenshots, each with its own per-branch baseline, so accepting a dark-mode change never touches the light-mode baseline. Modes also multiply your snapshot count - three modes is three billable snapshots - so declare the ones that matter and lean on dense stories to keep the total down.
How is a theme applied?
A mode's theme value is set as the theme:<value> Storybook global for that capture, and light/dark also emulate the OS color scheme (prefers-color-scheme). Your Storybook has to respond to that global - usually through your existing theme decorator or addon - just as it does under Chromatic, whose modes docs (checked 2026-10-17) also apply each mode's values as Storybook globals.
Do my Chromatic modes carry over?
Yes. UI Verify reads both parameters.uiVerify.modes and the Chromatic-compatible parameters.chromatic.modes (plus the legacy viewports width array), and uiVerify wins per key when a story sets both - so an existing Chromatic modes config renders the same variants with no change. A mode set to { disable: true } opts a story out of a mode it would otherwise inherit.
Visual testing for agents
UI Verify is visual regression testing for Playwright, Storybook, Vitest and Bun. Your coding agent sees what its UI change did and fixes it before it ships. See how it works.
Get started