Platform docs
Auth, users, webhooks & more
Info:
This is beta documentation for Stream Video React SDK v2. For the latest stable version, see the latest version (v1).

Theme

The React Video SDK ships with a default UI theme (CSS stylesheet) you can include in your application.

Best Practices

  • Import SDK styles before your own CSS for easier overrides.
  • Use CSS variables for theming instead of overriding component styles directly.
  • Use CSS cascade layers to simplify style overrides.
  • Test custom CSS rules after each SDK update - HTML/CSS structure may change.

Usage

Importing the CSS

Import the CSS stylesheet from the SDK's dist folder:

import "@stream-io/video-react-sdk/dist/css/styles.css";
// ideally, Stream Video theme should be imported before your own styles
// as this would make it easier for you to override certain video-theme rules
import "./my-styles.css";

Using the StreamTheme component

<StreamTheme /> renders an HTML element with the str-video CSS class, enabling the default theme for its children. It supports the as prop to render different elements (default: <div>), the theme prop to pick the light or dark theme (default: "dark"), and accepts any HTML attribute as props.

import { StreamTheme, StreamVideo } from "@stream-io/video-react-sdk";

export const App = () => {
  return (
    <StreamVideo client={client}>
      <StreamTheme as="main" className="my-custom-root-class">
        <MyAppUI />
      </StreamTheme>
    </StreamVideo>
  );
};

Customization

Override design tokens with CSS. Pick the selector by what you want to change:

You want to change Selector
A token in both light and dark .str-video
A token in one mode only .str-video__theme-light / .str-video__theme-dark
Only the SDK roots you mark with your own class .str-video.pronto, or .str-video.pronto.str-video__theme-dark for one mode

Most apps only need the first two. Use your own class when different parts of the app need different looks, for example a branded area next to the default UI.

The first two selectors have the same specificity as the SDK's own rules, so import your CSS after the SDK stylesheet or the SDK values win. Selectors with your own class are more specific and win in any order.

Theme variables

Customize colors, radii, spacing and icons using the design-token CSS variables defined in our light and dark token files, and the icons in the icons file. Use the .str-video selector to override them in both themes:

import '@stream-io/video-react-sdk/dist/css/style.css';

// Use your own font
html {
  font-family: sans-serif;
}

.str-video {
  --str-video__accent-primary: #6002ee;
  --str-video__text-primary: #282b2b;
  --str-video__radius-lg: 15px;
  --str-video__icon--download: url('base64 encoded SVG');
}

Light and dark themes

The SDK ships with a light and a dark theme. Dark is the default. Pick one with the theme prop:

import {
  StreamTheme,
  StreamVideo,
  type StreamThemeMode,
} from "@stream-io/video-react-sdk";
import { useState } from "react";

export const App = () => {
  const [theme, setTheme] = useState<StreamThemeMode>("dark");

  return (
    <StreamVideo client={client}>
      <button onClick={() => setTheme("dark")}>Dark theme</button>
      <button onClick={() => setTheme("light")}>Light theme</button>
      <StreamTheme theme={theme}>
        <MyAppUI />
      </StreamTheme>
    </StreamVideo>
  );
};

StreamTheme adds str-video__theme-light or str-video__theme-dark next to str-video. Menus and tooltips render inside it, so they follow the theme too. Content you render into a separate document, such as a Document Picture-in-Picture window, needs its own StreamTheme.

To customize one theme only, target its class. For example, a lighter shade of your accent keeps its contrast on dark surfaces:

@import "@stream-io/video-react-sdk/dist/css/styles.css";

.str-video__theme-light {
  --str-video__accent-primary: #7c3aed;
}

.str-video__theme-dark {
  --str-video__accent-primary: #a78bfa;
}

Custom brand theme

Add your own class next to theme to layer a brand theme on top of light and dark:

<StreamTheme theme={theme} className="pronto">
  <MyAppUI />
</StreamTheme>

Override only the tokens that make the theme yours. Rules on .str-video.pronto apply in both light and dark:

@import "@stream-io/video-react-sdk/dist/css/styles.css";

.str-video.pronto {
  --str-video__accent-primary: #7c3aed;
  --str-video__radius-lg: 16px;
}

For a brand value in one mode only, add the theme class to the selector, for example .str-video.pronto.str-video__theme-dark. .str-video.pronto is more specific than the SDK's .str-video and .str-video__theme-dark rules, so your values win regardless of stylesheet order.

Custom CSS code

For minor design tweaks, writing CSS is often easier than creating custom components. Note that HTML/CSS structure may change with any release - test custom CSS rules after SDK updates.

CSS cascade layers make overriding easier:

@import url("@stream-io/video-react-sdk/dist/css/styles.css")
layer(video-default);

.str-video__call-controls__button {
  padding: 20px;
}
Add Chat to my app: getstream.io/SKILL.md

The fastest way to build with Stream. Start a new project or improve an existing one. Full CLI and documentation integration out of the box.


Ask your agent:

/stream Build me a Social App with Feeds and Moderation.
/stream Any livestream calls running?
/stream Video React v2: <Your Question>