How to Test React Native UI Visually with Storybook and Chromatic

Why Visual Testing Matters for React Native Apps

Let's be honest. You've shipped a React Native update, tested it on a device, everything looked fine — then a user sends a screenshot of a button that's shifted three pixels to the left on their Android. Sound familiar?

That's the reality of mobile UI development. Unit tests verify logic. They tell you if a function returns the right value. But they won't catch a layout shift, a color mismatch, or a font that renders differently on iOS vs Android. Those are visual bugs, and they're everywhere.

The problem with manual UI checks

Most teams rely on developers squinting at screens during code review. Or worse, QA manually clicking through every screen before a release. This approach doesn't scale. A team of five might catch 80% of visual regressions. A team of twenty? Maybe 60%. Fatigue sets in. Humans miss things.

And here's the kicker: visual regression testing finds bugs that unit tests and integration tests completely ignore. A 1px padding change? Invisible to Jest. A font-weight that reverts to default? Your test suite won't blink. But your users will notice.

How visual regression testing saves time

Automated visual testing works by taking screenshots of your UI components and comparing them against a baseline. When you make changes, the tool highlights every pixel difference. You approve or reject those changes. No more manual hunting.

For React Native specifically, tools like Storybook combined with Chromatic give you a workflow that fits right into your existing development cycle. You write stories for your components, Chromatic captures the screenshots, and your CI pipeline flags anything unexpected. It's that straightforward.

So what exactly will you learn here? By the end of this guide, you'll have a fully working setup to test React Native UI visually — from installing Storybook to automating checks in CI. Let's get into it.

Prerequisites: What You Need Before Starting

Before we jump into the setup, make sure you've got the basics covered. Nothing worse than hitting a wall because you're missing a dependency.

React Native project setup

  • A working React Native project — either Expo or bare workflow. Both work fine with this setup.
  • Node.js 16+ and either npm or yarn installed.
  • Basic familiarity with React Native components and how your project is structured.

If you're starting from scratch, run npx react-native init MyVisualTestApp (or npx create-expo-app if you prefer Expo). Either way works.

Storybook for React Native

Storybook is the backbone here. It lets you develop and test UI components in isolation. You don't need to be an expert — just understand that a "story" is basically a function that renders your component with specific props. We'll use @storybook/react-native.

One thing to note: Storybook for React Native isn't the same as the web version. The setup is slightly different, and you'll run it on a device or simulator. But the concepts are identical.

Step 1: Install and Configure Storybook in React Native

This is where the rubber meets the road. Let's get Storybook running in your project.

Adding Storybook to your project

Run this command in your project root:

npx sb@latest init --type react_native

This scaffolds everything you need — a .storybook directory, configuration files, and a few example stories. If you get prompted about overwriting files, say yes unless you have custom config you want to keep.

After the install finishes, you'll see a .storybook folder containing main.js and preview.js. These control which stories get loaded and how they render. The default config usually points to ./src/stories or similar. You can change this later.

Creating your first component story

Let's write a simple story for a Button component. Create a file called Button.stories.tsx inside your stories folder:

import React from 'react';
import { Button } from 'react-native';
import { ComponentStory, ComponentMeta } from '@storybook/react-native';

export default {
  title: 'Button',
  component: Button,
} as ComponentMeta;

const Template: ComponentStory = (args) => 

Now run Storybook on your device or simulator:

npx storybook start

You should see your Button story rendered. If it works, you're ready for the next step. If not, double-check your main.js config — make sure it's pointing to the right directory.

Pro tip: Keep your stories co-located with your components. Instead of a separate stories folder, put Button.stories.tsx right next to Button.tsx. It makes maintenance easier.

Step 2: Integrate Chromatic for Visual Testing

Storybook gives you isolated component rendering. But that alone doesn't catch visual regressions. You need a tool that compares screenshots across builds. That's where Chromatic comes in.

Setting up a Chromatic project

Head over to chromatic.com and sign up. Create a new project — you'll need to connect it to your Git repository (GitHub, GitLab, or Bitbucket). Once done, Chromatic gives you a project token. Copy it. You'll need it in a moment. Connecting Chromatic to your Storybook Install the Chromatic package: npm install --save-dev chromatic Now add a script to your package.json: "chromatic": "npx chromatic --project-token=<YOUR_TOKEN>" Replace <YOUR_TOKEN> with the actual token from Chromatic. Do not commit this token to your repository. Use environment variables instead — we'll cover that in the CI section. That's it for setup. Seriously. Chromatic picks up your Storybook configuration automatically. It knows where your stories live and how to render them. Warning: If you're using Expo, you might need to adjust the build command. Chromatic expects a web-compatible Storybook build. For React Native, this usually means using @storybook/react-native with the getStorybookUI export. Check Chromatic's docs for the exact Expo setup — it's well-documented. Step 3: Run Your First Visual Test and Review Results Time to see this thing in action. Capturing baseline screenshots Run the Chromatic script: npm run chromatic Chromatic will start a local Storybook instance, render each of your stories, take screenshots, and upload them. The first run creates a baseline — a set of "correct" screenshots that future builds will be compared against. This first run might take a minute or two. Be patient. Once it finishes, you'll get a URL pointing to your Chromatic project dashboard. Reviewing changes in the Chromatic UI Now make a change to your Button component. Change the color from #007AFF to #FF3B30. Run npm run chromatic again. Open the dashboard. You'll see a side-by-side comparison: the baseline image on the left, the new build on the right. Any pixel differences are highlighted in pink. Chromatic shows you exactly what changed — the button color is now red instead of blue. From here, you have two options: Accept the change if it's intentional (you wanted to update the color). Reject it if it's a regression (someone accidentally changed the color). Rejected changes block your CI pipeline. That's the whole point — visual regression testing catches bugs before they reach production.

One thing I've learned: don't accept changes blindly. Review each diff carefully. Sometimes a 1px shift is actually a real bug hiding in plain sight.

Step 4: Automate Visual Testing in CI/CD

Running Chromatic manually is fine for a one-off test. But the real power comes when you automate it. Every pull request should trigger a visual check.

Adding Chromatic to GitHub Actions

Create a workflow file at .github/workflows/chromatic.yml:

name: Chromatic
on: push

jobs:
  chromatic:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: actions/setup-node@v4
        with:
          node-version: 18
      - run: npm ci
      - uses: chromaui/action@v1
        with:
          projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
          token: ${{ secrets.GITHUB_TOKEN }}

Add your Chromatic project token as a secret in your GitHub repository settings (Settings > Secrets and variables > Actions). Name it CHROMATIC_PROJECT_TOKEN.

Now every push runs Chromatic automatically. Pull requests show a check status — pass or fail. Your team can see visual diffs directly in the PR without leaving GitHub.

Best practices for team workflows

Here's what works in practice:

  • Set pixel thresholds. Chromatic lets you ignore tiny differences (like anti-aliasing). Start with a 0.1% threshold and adjust if you get too many false positives.
  • Review in pairs. Have one person approve UI changes, another review the code. Keeps both quality and consistency in check.
  • Combine with Sherlo's visual testing tools for deeper component-level analysis. Sherlo.io integrates seamlessly with React Native and gives you faster feedback loops — especially useful when you're iterating quickly on UI components.

Look, Chromatic handles the screenshot comparison well. But for more granular control — like testing component states, interactions, or animations — Sherlo's approach gives you an extra layer of confidence. It's worth exploring if you're serious about automated visual testing.

Troubleshooting Common Issues

No tool is perfect. Here are the most common problems you'll hit and how to fix them.

Handling platform-specific differences

iOS and Android render things differently. A button that looks perfect on iOS might have extra padding on Android. Chromatic will flag this as a diff — but it's not a real regression.

Solution: use platform-specific stories. Create Button.ios.stories.tsx and Button.android.stories.tsx with platform-appropriate props. Chromatic treats them as separate stories, so you won't get false positives.

Dealing with flaky snapshots

Dynamic content is the enemy of visual testing. Dates, random IDs, user avatars — they change every time, causing false diffs.

Wrap your stories in a decorator that mocks dynamic data. For example:

const withMockedDate = (Story) => {
  const MockDate = new Date('2025-01-01');
  jest.useFakeTimers().setSystemTime(MockDate);
  return ;
};

For animations, disable them entirely during testing. Add a global decorator in preview.js that sets useNativeDriver: false and reduces duration to 0.

Another gotcha: If your snapshots vary between runs on different machines, check for font rendering differences. Install the same fonts on your CI runner as on your local machine. This is a pain, but it matters.

Summary: Ship Confident UIs with Visual Testing

Let's recap what you've learned:

  1. Why visual testing matters — unit tests miss layout bugs, but visual regression testing catches them.
  2. Set up Storybook in your React Native project to render components in isolation.
  3. Integrate Chromatic to capture baseline screenshots and compare future builds.
  4. Run your first test — accept or reject visual changes from the dashboard.
  5. Automate in CI so every PR gets checked without manual effort.
  6. Troubleshoot common issues like platform differences and flaky snapshots.

The whole setup takes under an hour. And honestly? It pays for itself in the first week. You'll catch regressions that would have slipped through code review. Your QA team will thank you. Your users will never see that misaligned button.

For teams that want to go further, Sherlo.io offers integrated visual testing built specifically for React Native. It complements the Storybook + Chromatic workflow with deeper component analysis and faster feedback loops. Check it out if you're ready to level up your visual testing tools.

Now go ship that UI with confidence.

Najczesciej zadawane pytania

What is the purpose of using Storybook with React Native for UI testing?

Storybook allows you to develop and test React Native UI components in isolation, providing a visual playground where you can view different states, props, and variations of components without running the full app.

How does Chromatic enhance visual testing for React Native apps?

Chromatic automatically captures screenshots of your Storybook stories, compares them against baseline images, and detects visual changes or regressions, making it easy to review UI differences across commits.

What are the key steps to set up Storybook in a React Native project?

First, install Storybook for React Native using a command like `npx storybook init --type react_native`, then configure the storybook server and add stories for your components. Finally, run Storybook to view and test your UI in a browser or mobile emulator.

Can you test interactive UI behaviors like button presses or navigation with Storybook in React Native?

Yes, Storybook supports actions and addons that allow you to simulate user interactions (e.g., button presses) and verify that callbacks or navigation events work correctly without needing the full app context.

Why is visual regression testing important for React Native UI?

Visual regression testing ensures that UI changes (like styling, layout, or component updates) do not introduce unintended visual bugs across different screens or devices, maintaining a consistent user experience during development.