Frequently asked questions

If you have a question not covered in our documentation, contact us via our in-app chat.

Comparison with other tools

How is this compared to End-to-End testing tools like Selenium and Cypress?

Chromatic complements your existing End-to-End tests (Selenium or Cypress).

Get tests for free

You already write stories as a natural part of building UIs. Chromatic transforms those stories into tests. That gives you expansive yet accurate UI coverage without having to write new tests.

No test flake

E2E tests are intended to QA the “happy path”, but are time-consuming to create and brittle to maintain. They tend to be flaky because they rely on the application being in a certain state before running the tests. The tests also have to run in a specific order. Chromatic tests against the static Storybook build. That prevents false positives and negatives.

Much faster

Chromatic runs all tests in parallel at no extra cost or configuration. We optimize for the fastest test time by evaluating only the rendered UI. This focus allows Chromatic to run thousands of UI tests in less than a minute. Selenium/Cypress tests can take half an hour or more for an app of meaningful complexity. That said, we recommend you use various testing strategies (visual, unit, E2E) for comprehensive app coverage.

Can I get rid of my BrowserStack or Sauce subscription?

Our aim isn’t to replace services like Browserstack or Sauce. Cloud browser services are invaluable for verifying interactive behavior (e.g., clicking around the UI) and End-to-End testing but aren’t built or priced for visual testing.

Chromatic gives professional UI engineers a purpose-built service for visual testing which helps you reduce your reliance on cloud browser services. In practice, our customers typically scale back their usage and save a boatload of money while increasing their testing productivity.

How is Chromatic different from visual testing tools like Applitools and Percy?

Chromatic is a faster, simpler, and cost-effective alternative to Applitools or Percy that is built for UI components and component libraries. Our customers compare us favorably on developer experience and price.

Get a detailed breakdown »

Product differentiation:

  • Components are first-class citizens in Chromatic so our workflow is necessarily different

  • Deep integration with Storybook (we’re core maintainers)

  • Track each components baselines through branches and merges

  • Generate a living component library online

  • Rewind component history

  • Review components one at a time, approvals carry over from build to build

We’re proud of our developer experience:

  • “It just works” – sensible defaults out of the box, no writing webdriver tests or custom integrations

  • Lightning fast test runs (modern cloud architecture) with no cap on concurrency

  • Automatic PR badging for GitHub, GitLab, and Bitbucket

What if I already publish Storybook using S3, Heroku, Netlify, or Vercel?

You don’t need to do this anymore. Chromatic is a Storybook-optimized cloud service for frontend teams that includes collaboration, access control, versioning, history, and integrations with your existing tools. That said, we’re happy customers of those hosting services and recommend them for other situations.

Snapshot rendering

Where are my images and fonts?

Image and font rendering can be tricky. Resources that load from unpredictable or flaky sources may not load in time (15s) to capture. Workaround this by:

If your resources are behind a firewall, whitelist our domain so we can load your resources.

Why do my emojis look different in the snapshot versus on my machine?

Emojis are handled by your operating system’s emoji font. Most OSs have a different emoji font and those fonts tend to change over time. For example, if you view a story on a Mac you’ll get Apple’s set of emojis.

Chromatic captures Chrome and Firefox snapshots in a Linux environment. It includes a common set of emojis used by most systems. Those emojis will likely look different from emojis on a consumer OS like Mac or Windows. Unfortunately, there’s no workaround available at this time.

Where are my videos?

Videos are interactive and time-based which introduces inconsistencies in snapshots. Chromatic hides videos by default to prevent false positives. You’ll see a blank space where the video is supposed to render.

Why am I getting cross-origin errors with my stories?

Most likely you are calling into window.parent somewhere in your code. As we serve your Storybook preview iframe inside our www.chromatic.com domain this leads to a x-origin error as your code doesn’t have access to our frame (with good reason!).

Generally speaking it is a good idea to wrap calls like that in a try { } catch in case the code is running in a context where that’s not possible (e.g Chromatic).

Why is my content being cut off vertically in my snapshots?

Make sure there are no elements inadvertently cutting off content through the use of overflow or height styles.

For elements that have relative height styles based on the size of the viewport (such as height: 100vh), all content nested under that element will show up in a screenshot unless either overflow: hidden or overflow: scroll is used to hide what is outside of that element (and therefore outside of the viewport).

When Chromatic takes a screenshot for an element that has a viewport-relative height as well as styling to hide/scroll the overflow, a default viewport height of 900px will be used. This default is only used when we can’t detect a “natural” height for the outermost DOM element (root ancestor), for instance, in the case of scrollable divs.

To set the height, you can add a decorator for stories that wraps them in a container with a fixed height:

// MyComponent.stories.js|jsx

import { MyComponent } from './MyComponent';

export default {
  component: MyComponent,
  decorators:  [(Story) => <div style={{ margin: '3em' }}><Story/></div>],
  title: 'Example Story',
};
Why are components that render in a portal (tooltip, modal, menu) getting cut off?

Portals allow components to render arbitrary elements outside of the parent component’s initial DOM hierarchy. For example, tooltips, modals, and menus can be triggered by a nested button, but render close to the top of the DOM hierarchy using portals.

Chromatic uses the “natural” height for your component’s outermost DOM element (using Storybook’s #root element) to determine snapshot dimensions. But portals render outside of the Storybook #root element. This means that Chromatic can’t auto-detect their dimensions when capturing the snapshot. This can result in your snapshot looking “cut off”.

Snapshot portaled elements by adding a decorator that wraps stories in a fixed height container. Adjust the height to account for the total dimensions of your component and portal.

// MyComponent.stories.js|jsx

import { MyComponent } from './MyComponent';

export default {
  component: MyComponent,
  decorators:  [(Story) => <div style={{ height: '300px' }}><Story/></div>],
  title: 'Example Story',
};
How do I capture content inside scrollable divs?

Scrollable divs constrain the height of their children. Change the height of the scrollable div to ensure all content fits. It’s not possible for Chromatic to infer how tall scrollable divs are intended to be.

Why isn’t my modal or dialog captured?

If you use an “animateIn” effect set delay to ensure we snapshot when the animation completes.

If your component infers its dimensions from the layout of the surrounding DOM elements (e.g., it’s a modal that uses position:fixed), you’ll need to set the height of that component’s stories using a decorator.

// MyComponent.stories.js|jsx

import { MyComponent } from './MyComponent';

export default {
  component: MyComponent,
  decorators: [
    storyFn => (
      <div style={{ width: '1200px', height: '800px' }}>
        This is a decorator for modals and such {storyFn()}
      </div>
    ),
  ],
  title: 'Example Story',
};

export const StoryWithDimensions = () => <MyComponent/>
What if I have a modal component that doesn't define a width or height?

If your component infers its dimensions from the layout of the surrounding DOM elements (e.g., it’s a modal that uses position:fixed), you can set the height of that component’s stories using a decorator.

// MyComponent.stories.js|jsx

import { MyComponent } from './MyComponent';

export default {
  component: MyComponent,
  decorators: [
    storyFn => (
      <div style={{ width: '1200px', height: '800px' }}>
        This is a decorator for modals and such {storyFn()}
      </div>
    ),
  ],
  title: 'Example Story',
};

const Template = (args) => <MyComponent/>;

export const StoryWithDimensions = Template.bind({});
StoryWithDimensions.args = {};
Do you support taking snapshots of a component with multiple themes?

We recommend you render stories multiple times, one for each theme. Here’s a code snippet of how to configure Storybook to show the same story in multiple themes. This is how the snapshots will appear in Chromatic.

If you’d only like to see multiple themes side-by-side in Chromatic and not in your local Storybook, use isChromatic().

Why am I seeing a blank snapshot?

Blank snapshots are often caused by:

  • An “animateIn” effect—If your component use an “animateIn” effect set delay to ensure we snapshot when the animation completes.

  • Position:fixed—Fixed position elements may depend on viewport size but do not have dimensions themselves. Wrap your component in an element whose height and width are defined.

Learn more about debugging snapshots.

Why am I getting inconsistent or incorrect snapshots?

Checkout common reasons why snapshots render inconsistently and solutions here.

Why am I getting a failing build when ignoring an element?

By default, Chromatic’s diffing algorithm skips the DOM elements marked with either a .chromatic-ignore CSS class or data-chromatic="ignore" attribute.

However, if you’re using this functionality but notice the incoming changes are still being captured. In that case, you’ll need to ensure that both the baseline and new snapshots retain the same dimensions (e.g., width, height, and relative positioning).

Why is my tab component's width rendering inconsistently?

Certain UI libraries like Material calculate the dimensions of each tab by measuring the rendered width of the tab’s children using JavaScript (for example, via getBoundingClientRect()).

However, this can lead to inconsistent snapshots in cases where you load a custom font. Fonts affect the dimensions of text within tabs. Since custom fonts can load before, during, or after the tab component itself loads, the dimensions calculated by the tab component can also vary.

The solution we recommend is to use a <link rel="preload"> in your .storybook/preview-head.html to preload the font before the story renders. This ensures that the dimensions of the contents inside of the tab component remain consistent when measured.

Usage

How is UI Review different from UI Tests? How do I get the best functionality out of both?

In a nutshell, UI Tests prevent regressions (bugs), while UI Review is for gathering qualitative feedback from your team.

The modern development process moves quickly, and developers often fill in gaps according to their best guess. UI review is an opportunity for developers to sync with other teammates to get a final OK before shipping.

Here’s how we recommend using the workflows together:

  • UI Tests (commit vs. commit): Use like unit tests to catch UI regressions in components. Typically, a developer would be responsible for this. It ensures you don’t introduce any bugs as you build new features. You’ll get notified of bugs down to the commit.
  • UI Review (branch vs. branch): Once you’ve finished the first iteration of the implementation and think the PR is “done”, it’s now ready for review from stakeholders like your tech lead, designer, or PM. This workflow helps them review all the changes in a PR at once and gives them tools to give you precise feedback on stories.
Can I only take snapshots when a component's code changes?

We recommend taking snapshots on every build because it’s the most reliable way to catch UI regressions. Global dependencies, such as CSS or third-party APIs can affect the UI without the code changing.

What happens when I run out of snapshots on the free plan?

Free plans come with 5000 snapshots per month. Once free snapshots are exhausted, testing & review will become paused until the next month at which time Chromatic will again begin taking snapshots and functionality will automatically resume. Upgrading to a paid plan will immediately resume testing & review.

What happens to my snapshots if I don't use them?

Chromatic will reset the snapshot count monthly, calculated based on the day you’ve signed up. For instance, if you signed up on February 14th, your count will be reset on the 14th of each month. Any remaining snapshots from the previous month will not accumulate.

Where can I find my project token?

The project token is available on the Configure page of your project.

Navigate to the Manage page and click on the Configure tab

Why are the story names in Chromatic different than what I have in Storybook?

Chromatic follows Storybook’s naming best practice. The last level in the hierarchy is tracked as the component name.

export default {
  title: 'App/Components/Button',
  component: Button,
};

export const Primary = () => <Button primary>Button</Button>;
export const Secondary = () => <Button secondary>Button</Button>;

In the example above, Button is the component name, while Primary and Secondary are the story names respectively. If your Storybook is organized in a different way, that will affect how your components and story names appear in both Chromatic and Storybook. There’s no way to configure name detection.

Folks often encounter naming issues when customizing their Storybook sidebar. In most cases, you can achieve your desired groupings while also adhering to naming best practices using these organizational tips.

Browsers

Can I disable Chrome?

All plans use Chrome by default because it offers the greatest test coverage for most people. It cannot be disabled.

Can I change which browser generates comparisons for UI Review?

No. At the moment, Chrome is fixed as the browser used for UI review.

How do browsers affect my snapshot count?

Each browser adds another snapshot for each of your stories. For example, if you have a story that is tested in Chrome and IE11, that counts as two snapshots.

If you also test your story with different viewports, those count as snapshots as well. For example, you want to test a story at 320px, 1280px, Chrome, and IE11. This would count as 4 snapshots.

Does adding more browser coverage add time to my tests?

Yes it can. We do our best to provide the fastest test speeds but there are limits to browser performance (IE11) even when scaled across hundreds and thousands of machines.

What about testing in every other browser and its versions?

Chromatic covers the major rendering engines (Blink, Gecko and Trident) at all viewports. This eliminates almost all browser regressions your users are likely to see with minimal effort, configuration, or additional time to your workflow.

Supporting more browser/device combinations ends up having diminishing returns that adds noise to the visual review process.

UI Tests and UI Review

Do I use more snapshots when both UI Tests and UI Review are enabled?

No. Snapshots taken for one workflow are reused for the other. You don’t get charged twice.

What happens if I disable UI Tests and/or UI Review?

As long as either the testing or review features are enabled, Chromatic will continue taking snapshots. With both disabled, Chromatic will stop taking snapshots and all other features of the platform (such as publishing) will continue without limits.

Continuous Integration

How to run Chromatic on a specific branch or only when merging to main?

How Chromatic is triggered depends on your Continuous Integration (CI) setup. You can configure your CI provider to run Chromatic on a specific branch or only when merging to your main branch. Please beware that changing which branches Chromatic runs on may affect test and review coverage because Chromatic uses Git history to track baselines.

For example, here’s how GitHub Actions can be configured:

TurboSnap

Why isn’t TurboSnap working for me?

TurboSnap is not compatible with squash and merge rebasing (learn more). Or you might be missing one of the necessary prerequisites.

Storybook Connect Figma plugin

Can you choose which version of the design from a Storybook is shown in Figma?

Yes, you can select which branch’s stories are connected to Figma.

Chromatic generates a unique permalink when a Storybook is published. You can link your component by using the URL to a specific commit or a permalink to a branch.

However, once linked, the plugin will always display stories from the latest build for that branch.

Does the Figma integration sync automatically?

Yes. Chromatic automatically updates your linked stories to reflect the latest build on the designated branch. That means even when the build URL for a branch changes in Chromatic, the Figma component will always display the latest build on the branch.

How do permissions work?

Figma users must have access to the Chromatic project in order to use the plugin. That means Figma collaborators (viewers, editors, admins) that have access to your Figma file but don’t have access to Chromatic will not be able to see the stories.

Learn how to invite teammates as collaborators on your Chromatic project. We don’t charge “per seat”, so you can invite your whole team. They must be able to see the story in Chromatic to be able to see it in the plugin.

What permissions do I need in Figma?

You require a Figma editor role to both link and view stories with this plugin.

Your account

How do I change my email and password?

If you signed up via OAuth, Chromatic will retrieve the email addresses associated with your account from your Git provider. Check your provider’s account settings page on how to add or change your email(s).

If you signed up via email, go to the Profile page to change your email address and password. Get there by signing in and clicking on your avatar in the header.

How do I change my username?

If you signed up via email, you’ll be assigned a username based on your email. Go to the Profile page to change your username. Get there by signing in and clicking on your avatar in the header.