Theme

Most stream-chat-react-native components can be styled via the theming system.

Best Practices

  • Use DeepPartial<Theme> to override only the keys you need.
  • Keep theme objects stable (store in state) to avoid unnecessary merges/re-renders.
  • Update the theme only when the color scheme changes.
  • Use useTheme inside custom components instead of hardcoding colors.
  • Refer to the default theme file to discover valid keys and types.

Setting the theme

Use the exported types to ensure your theme keys are valid. Your theme is deep-merged with defaults, so you only need to set the keys you want to override. Use DeepPartial to make all keys optional.

The default theme lives in theme.ts.

Most keys are standard React Native styles, but some SVG/Markdown/custom component styles are numbers, strings, or specific types. See the TypeScript docs for Theme. Message text uses react-native-markdown-package, with MarkdownStyle on messageSimple -> content -> markdown.

import type { DeepPartial, Theme } from "stream-chat-react-native";

const theme: DeepPartial<Theme> = {
  messageSimple: {
    file: {
      container: {
        backgroundColor: "red",
      },
    },
  },
};

Pass the theme via the value.style prop on OverlayProvider.

import { Chat, ChannelList, OverlayProvider } from "stream-chat-react-native";

const style = { style: theme };

export const App = () => (
  <OverlayProvider value={style}>
    <Chat client={client}>
      <ChannelList />
    </Chat>
  </OverlayProvider>
);

Using the theme

Access the theme in custom components with useTheme. Avoid memoizing theme values so updates propagate.

const {
  theme: {
    colors: { black },
  },
} = useTheme();

Dark mode

For dark mode, build a theme from useColorScheme. Keep it in state and update only when the scheme changes to avoid extra merges and re-renders.

import { useEffect, useState } from "react";
import { useColorScheme } from "react-native";
import type { DeepPartial, Theme } from "stream-chat-react-native";

const getTheme = (): DeepPartial<Theme> => ({
  colors: colorScheme === "dark" ? { black: "#FFFFFF" } : { black: "#000000" },
});

export const App = () => {
  const colorScheme = useColorScheme();
  const [theme, setTheme] = useState(getTheme());

  useEffect(() => {
    setTheme(getTheme());
  }, [colorScheme]);

  return (
    <OverlayProvider value={{ style: theme }}>
      <Chat client={client}>
        <ChannelList />
      </Chat>
    </OverlayProvider>
  );
};