Skip to main content
  • Goal: Customize UI Kit appearance (colors, fonts, dark mode)
  • Where: App.css (global) — import in app entry via import "./App.css";
  • Step 1: Import base stylesheet: @import url("@cometchat/chat-uikit-react/css-variables.css");
  • Step 2: Override variables on .cometchat (global) or .cometchat-<component> (component-specific)
  • Step 3: For dark mode, override on .cometchat-root[data-theme="dark"] .cometchat or use @media (prefers-color-scheme: dark)
  • Key tokens: --cometchat-primary-color, --cometchat-neutral-color-300, --cometchat-font-family, --cometchat-background-color-03
  • Constraints: Global CSS only (no CSS Modules), no !important, component-level overrides beat global
  • Full token list: Color Resources | GitHub source
Theming allows you to define the look and feel of your app by adjusting colors, fonts, and other styles. Using CSS variables, you can create a consistent and on-brand chat experience.
Prerequisites before applying any theming:
  1. Import the base stylesheet: @import url("@cometchat/chat-uikit-react/css-variables.css"); in your App.css
  2. Import your CSS file at the app entry: import "./App.css"; in App.tsx
  3. All selectors assume the UI Kit renders under a .cometchat root wrapper
  4. Use global CSS (not CSS Modules with hashed class names) — hashed selectors won’t match

Root Wrapper (.cometchat)

All selectors in this doc are scoped under .cometchat, which is the class the UI Kit renders on its root element. If you already wrap your chat UI in a container (commonly cometchat-root in examples), keep it — just make sure your overrides target .cometchat inside.
export default function App() {
  return (
    <div className="cometchat-root">
      {/* UI Kit components */}
    </div>
  );
}
If you use data-theme, put it on the wrapper you control and scope your dark theme overrides to .cometchat inside.

Theming Contract

Inputs
  • Base stylesheet import: @import url("@cometchat/chat-uikit-react/css-variables.css");
  • Global CSS variables on .cometchat
  • Component-scoped variables on .cometchat .cometchat-<component>
  • Optional element-level CSS overrides for specific selectors
  • Optional theme mode selector: .cometchat-root[data-theme="dark"] .cometchat or @media (prefers-color-scheme: dark)
Scope
  • Always scope overrides under .cometchat to avoid leaking styles into the host app.
Precedence
  1. Element-level CSS overrides (most specific)
  2. Component-scoped variables (.cometchat .cometchat-conversations { --var })
  3. Global variables (.cometchat { --var })
  4. Defaults from css-variables.css (least specific)
Expected outputs
  • Primary tokens change outgoing bubbles, buttons, and active states.
  • Background tokens change panels and surfaces.
  • Text/icon tokens change highlight accents.
  • Font tokens change typography across the UI.

Importing the Stylesheet

To enable theming, first, import the base stylesheet containing default styles and variables.
@import url("@cometchat/chat-uikit-react/css-variables.css");

Global Theming with CSS Variables

Customize the entire chat UI by overriding CSS variables in your global stylesheet.

Example: Changing Colors & Fonts

The following CSS variables customize colors, fonts, and other elements.
Recommended: Use App.css for global overrides and keep them scoped under .cometchat. Use the runtime setProperty approach only when you need live theme changes without a reload.
Expected result: All primary-colored elements (outgoing bubbles, buttons, active states, links) change to orange (#f76808). Background panels change to light peach (#feede1). Font changes to Times New Roman.

Top Tokens (Quick Mapping)

Use this table for fast, reliable overrides. For the complete list, see Color Resources.
TokenCommon usage (varies by component)
--cometchat-primary-colorPrimary accent color (buttons, outgoing bubbles, active states)
--cometchat-extended-primary-color-900Darker primary shade (outgoing bubble shade)
--cometchat-extended-primary-color-500Mid primary shade (secondary accents/hover)
--cometchat-neutral-color-300Neutral surface (incoming bubbles/panels)
--cometchat-background-color-03Panel background surface
--cometchat-text-color-highlightHighlight text color
--cometchat-icon-color-highlightHighlight icon color
--cometchat-message-seen-colorSeen/read indicator color
--cometchat-font-familyGlobal font family
--cometchat-radius-maxMaximum corner radius used across UI elements

Component-Specific Theming

Want to apply different styles to specific components? Override CSS variables within the component’s class.
.cometchat .cometchat-conversations {
  --cometchat-primary-color: #f76808;
  --cometchat-extended-primary-color-500: #fbaa75;
  --cometchat-text-color-highlight: #ffab00;
  --cometchat-message-seen-color: #f76808;
  --cometchat-radius-max: 12px;
}
Expected result: Only the Conversations component changes — primary color becomes orange, highlight text becomes amber, avatars get 12px border radius. Other components remain unchanged.

Advanced Customization with CSS Overrides

For full control over component styling, use CSS overrides to target specific elements directly.
.cometchat-conversations .cometchat-avatar,
.cometchat-conversations .cometchat-avatar__image {
  border-radius: 12px;
}
Expected result: Avatar images in the Conversations list change from circular to rounded-square (12px radius).

Dark & Light Theme Support

You can switch between light and dark modes.
Choose ONE dark mode strategy:
  1. App-controlled: set data-theme on your wrapper (e.g., .cometchat-root) and scope overrides like .cometchat-root[data-theme="dark"] .cometchat { ... }
  2. OS-controlled: use @media (prefers-color-scheme: dark) scoped to .cometchat Avoid mixing both unless you intentionally want OS preference plus manual overrides.

Example: Enabling Dark Mode

import { useEffect, useState } from "react";

const App = () => {
  const [theme, setTheme] = useState("light");

  useEffect(() => {
    const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
    setTheme(mediaQuery.matches ? "dark" : "light");

    const handleThemeChange = (e: MediaQueryListEvent) => {
      setTheme(e.matches ? "dark" : "light");
    };

    mediaQuery.addEventListener("change", handleThemeChange);
    return () => mediaQuery.removeEventListener("change", handleThemeChange);
  }, []);

  return <div className="cometchat-root" data-theme={theme}>{/* Chat UI here */}</div>;
};

export default App;
Expected result: The wrapper tracks the user’s OS preference and sets data-theme, which you can use to switch palettes in your CSS.

Customizing Light & Dark Theme

Define different color schemes for light and dark modes.
/* Default (Light) Theme */
.cometchat {
  --cometchat-primary-color: #f76808;
  --cometchat-neutral-color-300: #fff;
  --cometchat-background-color-03: #feede1;
  --cometchat-extended-primary-color-500: #fbaa75;
  --cometchat-icon-color-highlight: #f76808;
  --cometchat-text-color-highlight: #f76808;
}

/* Dark Theme */
.cometchat-root[data-theme="dark"] .cometchat {
  --cometchat-primary-color: #f76808;
  --cometchat-neutral-color-300: #311502;
  --cometchat-background-color-03: #451d02;
  --cometchat-extended-primary-color-500: #943e05;
  --cometchat-icon-color-highlight: #f76808;
  --cometchat-text-color-highlight: #f76808;
  --cometchat-message-seen-color: #f76808;
  --cometchat-neutral-color-50: #1a1a1a;
}
If you prefer OS-controlled dark mode, wrap the dark overrides in @media (prefers-color-scheme: dark) and keep the .cometchat scope. Expected result: Light mode uses orange (#f76808) with peach backgrounds; dark mode uses the same orange accent but with dark brown backgrounds (#311502, #451d02) for proper contrast.

Examples

1) Brand color swap (global)

Where: App.css
.cometchat {
  --cometchat-primary-color: #0f766e;
  --cometchat-extended-primary-color-500: #14b8a6;
  --cometchat-text-color-highlight: #0f766e;
  --cometchat-icon-color-highlight: #0f766e;
}
Expected result: Primary accents, buttons, and active states switch to teal.

2) Dark mode (app-controlled)

Where: App.css + set data-theme on the .cometchat wrapper
.cometchat-root[data-theme="dark"] .cometchat {
  --cometchat-background-color-03: #121212;
  --cometchat-neutral-color-300: #1e1e1e;
  --cometchat-text-color-highlight: #f76808;
}
Expected result: Panels and surfaces darken while accents remain visible.

3) Conversations-only override

Where: App.css
.cometchat .cometchat-conversations {
  --cometchat-primary-color: #f76808;
  --cometchat-message-seen-color: #f76808;
  --cometchat-radius-max: 12px;
}
Expected result: Only the Conversations component changes; other components stay default.

4) Bubble styling (incoming/outgoing)

Where: App.css
.cometchat .cometchat-message-bubble-outgoing .cometchat-message-bubble__body {
  --cometchat-primary-color: #f76808;
  --cometchat-extended-primary-color-900: #fbaa75;
}

.cometchat .cometchat-message-bubble-incoming .cometchat-message-bubble__body {
  --cometchat-neutral-color-300: #f1f5f9;
}
Expected result: Outgoing bubbles use orange; incoming bubbles use a light slate. For more variants, see Message Bubble Styling.

Common Failure Modes

SymptomCauseFix
CSS has no effectCSS file not imported in app entryAdd import "./App.css"; in App.tsx
CSS has no effectBase stylesheet not importedAdd @import url("@cometchat/chat-uikit-react/css-variables.css"); at top of App.css
Overrides not applyingMissing .cometchat scope in selectorEnsure your overrides are scoped under .cometchat
Selectors don’t matchUsing CSS Modules (hashed class names)Move rules to a global stylesheet, not *.module.css
Component-level override not workingMissing .cometchat parent in selectorUse .cometchat .cometchat-conversations not just .cometchat-conversations
Dark mode unchangeddata-theme missing or mismatchSet data-theme="dark" on your wrapper (e.g., .cometchat-root) and target .cometchat-root[data-theme="dark"] .cometchat, or use @media (prefers-color-scheme: dark)
Font not changing--cometchat-font-family set on wrong elementSet on .cometchat or via a ref to the .cometchat wrapper
Styles leak into host appMissing .cometchat scope prefixAlways scope overrides under .cometchat
Token change has no visible effectToken doesn’t control the property you expectCheck the Color Resources table for what each token controls

Helpful Resources

Enhance your design and development workflow with the following resources:

UI Kit Source Code

Explore the complete list of color variables and hex values on GitHub.View on GitHub

Figma UI Kit

Access the Figma UI Kit for a fully integrated color palette and seamless customization.View on Figma

Next Steps