Introduction

The SDK ships with default CSS that you can override.

Best Practices

  • Prefer CSS variables over selector overrides to keep upgrades painless.
  • Use CSS layers (stream, stream-overrides) so overrides remain readable and conflict-free.
  • Scope theme changes to .str-chat to avoid leaking styles into the rest of the app.
  • Use component variables when you need targeted changes without global side effects.
  • Use the root dist/css/* entrypoints; legacy /v2/ style import paths no longer resolve.

Importing the stylesheet

@import "stream-chat-react/dist/css/index.css" layer(stream);

Most examples use the CSS layers API to keep override specificity predictable.

Customization

The theming system supports both small and large UI changes. This document walks through the available options.

CSS variables

CSS variables are the easiest way to customize the theme. They’re organized into two tiers:

  • global
  • component

Global variables

Use global variables to change the overall chat UI (instead of individual components).

The full list of global variables can be found in our global variables guide.

Here is the default chat UI:

Default Stream Chat React UI

Here is how you can customize global variables:

@layer stream, stream-overrides;
@import "stream-chat-react/dist/css/index.css" layer(stream);
@layer stream-overrides {
  .str-chat {
    /* Accent color — used by mentions, read receipts, attachment actions, focus states, etc. */
    --accent-primary: #0d47a1;

    /* Message bubble colors */
    --chat-bg-outgoing: #1e3a8a;
    --chat-bg-attachment-outgoing: #0d47a1;
    --chat-bg-incoming: #dbeafe;
    --chat-text-outgoing: #ffffff;
    --chat-reply-indicator-outgoing: #93c5fd;

    /* Link colors (inside bubbles and elsewhere) */
    --text-link: #1e40af;
    --chat-text-link: #93c5fd;

    /* Panel backgrounds */
    --background-core-elevation-1: #dbeafe; /* channel list and surrounding panels */
    --background-core-app: #c7dafc; /* message list background */

    /* Focus ring */
    --border-utility-focused: #1e40af;

    /* Radii — the SDK uses --radius-max / --button-radius-full for pill shapes */
    --radius-max: 8px;
    --button-radius-full: 6px;
  }
}

Here is the result:

Stream Chat CSS Chat UI Theme Customization

The str-chat class is applied to the ChannelList and Channel components, and the SDK's global tokens are declared at this level — so scoping your overrides here reaches both panes.

Component variables

You can use component layer variables to change the design of individual components. The full list of component variables can be found in our component variables guide.

To change avatar colors without affecting the rest of the UI, use avatar-specific variables:

@layer stream-overrides {
  .str-chat {
    /* Accent + bubble colors from the previous example */
    --accent-primary: #0d47a1;
    --chat-bg-outgoing: #1e3a8a;
    --chat-text-outgoing: #ffffff;
    --chat-bg-incoming: #dbeafe;

    /* Avatar colors (v14 tokens) */
    --avatar-bg-default: #bf360c;
    --avatar-text-default: #ffffff;
  }
}

Here is the result:

Stream Chat React UI With Custom Avatar Color

Component variables are local to their component — overriding one doesn't cascade into others. Here is the default message bubble:

Stream Chat CSS Message Color

And with a custom text color set via the component token:

@layer stream-overrides {
  .str-chat {
    --accent-primary: #0d47a1;
    --chat-bg-outgoing: #1e3a8a;
    --chat-text-outgoing: #ffffff;
    --chat-bg-incoming: #dbeafe;
    --avatar-bg-default: #bf360c;
    --avatar-text-default: #ffffff;

    /* Component token: message bubble text color */
    --str-chat__message-bubble-color: #00695c;
  }
}

Stream Chat React UI With Custom Message

In v14 the message bubble and its link-attachment card share the same text color through the --chat-text semantic token, which resolves to --chat-text-outgoing or --chat-text-incoming depending on who sent the message. If you want bubble text and link attachments to match, override --chat-text-outgoing / --chat-text-incoming at the .str-chat scope instead of the component-level --str-chat__message-bubble-color.

Dark and light themes

The default theme has dark and light variants. Here is how you can switch between the different themes:

<Chat client={client} theme="str-chat__theme-dark">
  {/* ... */}
</Chat>

or only to a specific component (Channel or/and ChannelList):

<Chat
  client={client}
  customClasses={{
    channelList: "str-chat__theme-dark str-chat__channel-list",
    channel: "str-chat__theme-light str-chat__channel",
  }}
>
  {/* ... */}
</Chat>

Using the customClasses approach for either of the components will override default class names. Remember to add those to your theme class names (as defined in the snippet) for the styling to work properly.

Here is what the dark theme looks like:

Stream Chat React UI in Dark Theme

The str-chat__theme-dark/str-chat__theme-light class is applied to the ChannelList and Channel components, these classes are responsible for switching between the dark and light theme color combinations.

Here is how you can provide different color configurations for the dark and light themes:

@layer stream, stream-overrides;
@import "stream-chat-react/dist/css/index.css" layer(stream);
@layer stream-overrides {
  /* Shape tokens shared by both themes */
  .str-chat {
    --radius-max: 8px;
    --button-radius-full: 6px;
  }

  /* Light theme palette */
  .str-chat__theme-light {
    --accent-primary: #0d47a1;
    --chat-bg-outgoing: #1e3a8a;
    --chat-bg-incoming: #dbeafe;
    --chat-text-outgoing: #ffffff;
    --text-link: #1e40af;
    --background-core-elevation-1: #dbeafe;
    --background-core-app: #c7dafc;
    --avatar-bg-default: #bf360c;
    --avatar-text-default: #ffffff;
  }

  /* Dark theme palette */
  .str-chat__theme-dark {
    --accent-primary: #4a90e2;
    --chat-bg-outgoing: #1e3a8a;
    --chat-bg-incoming: #1f2937;
    --chat-text-outgoing: #e2e8f0;
    --chat-text-incoming: #e2e8f0;
    --text-link: #93c5fd;
    --background-core-elevation-1: #0f172a;
    --background-core-app: #020617;
    --avatar-bg-default: #ff7043;
    --avatar-text-default: #ffffff;
  }
}

Here is the custom dark theme:

Stream Chat React UI With a Custom Dark Theme

Creating your own theme

You can extend the built-in themes with your own. Here is an example creating round and square themes:

@layer stream, stream-overrides;
@import "stream-chat-react/dist/css/index.css" layer(stream);
@layer stream-overrides {
  .str-chat__theme-round {
    --radius-max: 9999px;
    --button-radius-full: 9999px;
  }

  .str-chat__theme-square {
    --radius-max: 6px;
    --button-radius-full: 6px;
  }
}
<Chat client={client} theme="str-chat__theme-square">
  {/* ... */}
</Chat>

or only to a specific component (Channel or/and ChannelList):

<Chat
  client={client}
  customClasses={{
    channelList: "str-chat__theme-square str-chat__channel-list",
    channel: "str-chat__theme-round str-chat__channel",
  }}
>
  {/* ... */}
</Chat>

Using the customClasses approach for either of the components will override default class names. Don't forget to add those to your theme class names (as defined in the snippet) for the styling to work properly.

Stream Chat React UI With a Square Theme

RTL support

The layout was built with RTL support in mind. You can use the RTL layout by providing the dir attribute in your HTML:

<html dir="rtl">
  <!-- ... -->
</html>

Here is the result:

Stream Chat React UI Rendered in Right-to-Left Layout