Skip to main content
The Backgrounds Addon allows you to visualize your components against different background colors. This is essential for testing component appearance in various contexts, such as light and dark themes, or ensuring proper contrast.

Installation

1

Install the addon

npm install -D @storybook/addon-ondevice-backgrounds
2

Register the addon

Add the addon to your .rnstorybook/main.ts configuration:
.rnstorybook/main.ts
import type { StorybookConfig } from '@storybook/react-native';

const main: StorybookConfig = {
  addons: ['@storybook/addon-ondevice-backgrounds'],
};

export default main;

Basic Usage

Define background options in your story’s parameters:
Card.stories.tsx
import type { Meta, StoryObj } from '@storybook/react-native';
import { Text, StyleSheet } from 'react-native';

const Card = () => (
  <Text style={styles.text}>Change background via Addons → Background</Text>
);

const styles = StyleSheet.create({
  text: { color: 'black' },
});

const meta = {
  component: Card,
  parameters: {
    backgrounds: {
      options: {
        warm: { name: 'Warm', value: 'hotpink' },
        cool: { name: 'Cool', value: 'deepskyblue' },
        white: { name: 'White', value: 'white' },
        black: { name: 'Black', value: 'black' },
      },
    },
  },
} satisfies Meta<typeof Card>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Basic: Story = {};
Users can now select from the defined backgrounds using the Backgrounds panel in the Storybook UI.

Setting a Default Background

Specify which background should be active by default using globals:
Card.stories.tsx
import type { Meta, StoryObj } from '@storybook/react-native';
import { Card } from './Card';

const meta = {
  component: Card,
  parameters: {
    backgrounds: {
      options: {
        light: { name: 'Light', value: '#ffffff' },
        dark: { name: 'Dark', value: '#000000' },
      },
    },
  },
} satisfies Meta<typeof Card>;

export default meta;

type Story = StoryObj<typeof meta>;

export const OnDarkBackground: Story = {
  globals: {
    backgrounds: { value: 'dark' },
  },
};

Background Configuration

Options Object

The options object maps background keys to their display configuration:
parameters: {
  backgrounds: {
    options: {
      // Key can be any string
      light: { 
        name: 'Light Theme',  // Display name in UI
        value: '#f8f9fa'      // CSS color value
      },
      dark: { 
        name: 'Dark Theme', 
        value: '#1a1a1a' 
      },
    },
  },
}

Color Values

Backgrounds support all standard CSS color formats:
parameters: {
  backgrounds: {
    options: {
      // Named colors
      white: { name: 'White', value: 'white' },
      
      // Hex colors
      gray: { name: 'Gray', value: '#808080' },
      
      // RGB
      blue: { name: 'Blue', value: 'rgb(0, 123, 255)' },
      
      // RGBA (with transparency)
      transparent: { name: 'Semi-transparent', value: 'rgba(0, 0, 0, 0.5)' },
      
      // HSL
      purple: { name: 'Purple', value: 'hsl(270, 100%, 50%)' },
    },
  },
}

Common Patterns

Light and Dark Themes

Test components in both light and dark modes:
ThemedCard.stories.tsx
import type { Meta, StoryObj } from '@storybook/react-native';
import { ThemedCard } from './ThemedCard';

const meta = {
  component: ThemedCard,
  parameters: {
    backgrounds: {
      options: {
        light: { name: 'Light Mode', value: '#ffffff' },
        dark: { name: 'Dark Mode', value: '#121212' },
      },
    },
  },
} satisfies Meta<typeof ThemedCard>;

export default meta;

type Story = StoryObj<typeof meta>;

export const LightTheme: Story = {
  globals: {
    backgrounds: { value: 'light' },
  },
};

export const DarkTheme: Story = {
  globals: {
    backgrounds: { value: 'dark' },
  },
};

Brand Colors

Test components against your brand’s color palette:
Logo.stories.tsx
import type { Meta, StoryObj } from '@storybook/react-native';
import { Logo } from './Logo';

const meta = {
  component: Logo,
  parameters: {
    backgrounds: {
      options: {
        brand: { name: 'Brand Primary', value: '#0066cc' },
        brandDark: { name: 'Brand Dark', value: '#004080' },
        neutral: { name: 'Neutral', value: '#f5f5f5' },
        white: { name: 'White', value: '#ffffff' },
      },
    },
  },
} satisfies Meta<typeof Logo>;

export default meta;

Accessibility Testing

Test contrast ratios by viewing components on different backgrounds:
AccessibleButton.stories.tsx
import type { Meta, StoryObj } from '@storybook/react-native';
import { Button } from './Button';

const meta = {
  component: Button,
  parameters: {
    backgrounds: {
      options: {
        white: { name: 'White (#fff)', value: '#ffffff' },
        lightGray: { name: 'Light Gray (#f0f0f0)', value: '#f0f0f0' },
        mediumGray: { name: 'Medium Gray (#888)', value: '#888888' },
        darkGray: { name: 'Dark Gray (#333)', value: '#333333' },
        black: { name: 'Black (#000)', value: '#000000' },
      },
    },
  },
} satisfies Meta<typeof Button>;

export default meta;

Global Configuration

Define backgrounds globally in .rnstorybook/preview.tsx to apply them to all stories:
.rnstorybook/preview.tsx
import type { Preview } from '@storybook/react-native';

const preview: Preview = {
  parameters: {
    backgrounds: {
      options: {
        light: { name: 'Light', value: '#ffffff' },
        dark: { name: 'Dark', value: '#000000' },
        gray: { name: 'Gray', value: '#f0f0f0' },
      },
    },
  },
};

export default preview;
Individual stories can override or extend these global backgrounds.

Overriding Per Story

Override global backgrounds for specific stories:
export const CustomBackgrounds: Story = {
  parameters: {
    backgrounds: {
      // Completely replace global backgrounds
      options: {
        custom1: { name: 'Custom 1', value: '#ff6b6b' },
        custom2: { name: 'Custom 2', value: '#4ecdc4' },
      },
    },
  },
};

Disabling Backgrounds

Disable the backgrounds addon for specific stories:
export const NoBackgrounds: Story = {
  parameters: {
    backgrounds: {
      disable: true,
    },
  },
};

Complete Example

Here’s a comprehensive example:
BackgroundExample.stories.tsx
import type { Meta, StoryObj } from '@storybook/react-native';
import { Text, StyleSheet, View } from 'react-native';

const BackgroundDemo = () => (
  <View style={styles.container}>
    <Text style={styles.text}>Try changing the background!</Text>
    <Text style={styles.subtext}>Use Addons → Background to switch themes</Text>
  </View>
);

const styles = StyleSheet.create({
  container: {
    padding: 20,
  },
  text: {
    fontSize: 18,
    fontWeight: 'bold',
    color: '#333',
  },
  subtext: {
    fontSize: 14,
    color: '#666',
    marginTop: 8,
  },
});

const meta = {
  component: BackgroundDemo,
  parameters: {
    backgrounds: {
      options: {
        warm: { name: 'Warm', value: 'hotpink' },
        cool: { name: 'Cool', value: 'deepskyblue' },
        white: { name: 'White', value: 'white' },
        black: { name: 'Black', value: 'black' },
      },
    },
  },
} satisfies Meta<typeof BackgroundDemo>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {};

export const OnWarmBackground: Story = {
  globals: {
    backgrounds: { value: 'warm' },
  },
};

export const OnCoolBackground: Story = {
  globals: {
    backgrounds: { value: 'cool' },
  },
};

export const OnDarkBackground: Story = {
  globals: {
    backgrounds: { value: 'black' },
  },
  parameters: {
    notes: 'Testing component visibility on dark backgrounds',
  },
};

TypeScript Support

The Backgrounds addon is fully typed:
import type { Meta } from '@storybook/react-native';

interface BackgroundOption {
  name: string;
  value: string;
}

interface BackgroundsParameter {
  options?: Record<string, BackgroundOption>;
  disable?: boolean;
}

const meta = {
  parameters: {
    backgrounds: {
      options: {
        light: { name: 'Light', value: '#fff' },
      },
    } satisfies BackgroundsParameter,
  },
} satisfies Meta;

Differences from Web Backgrounds

The React Native Backgrounds addon uses a slightly different API than the web version:

Web Format (not supported)

backgrounds: {
  default: 'light',
  values: [
    { name: 'light', value: '#fff' },
    { name: 'dark', value: '#000' },
  ],
}

React Native Format (supported)

backgrounds: {
  options: {
    light: { name: 'Light', value: '#fff' },
    dark: { name: 'Dark', value: '#000' },
  },
}
The web Storybook documentation may use the values array format, but the React Native addon uses the options object format shown above.

Controls Addon

Test component props with different backgrounds

Web Backgrounds Docs

Official web backgrounds documentation (API differs)

Build docs developers (and LLMs) love