Info:
This is release candidate documentation for Stream Chat React Native SDK v10. For the latest stable version, see the latest version (v9).

Design tokens

The design tokens are the SDK's named colors, spacing, corner radii, type sizes and shadows. The components build their styles from them. For example, the bubbles of the user's own messages use the chatBgOutgoing token, which points at brand100, which is the blue100 color, #e3edff, in the light scheme.

The tokens come in four tiers. Only the semantic tokens are part of the theme, under theme.semantics, so they're the only tokens you can override. This page lists every token with its value on iOS and Android, in the light and the dark scheme. Theme object lists the rest of the theme, and Theming shows how to set it.

How the tokens are organized

Each tier is built from the one above it:

Tier What it holds Part of the theme
Foundations Raw values. Ten color scales, black, white and a few transparent colors, and the scales of sizes, radii, spacing, stroke widths and type No
Primitives Values for a purpose, such as spacing (spacingMd), radii (radiusLg), type sizes and weights (typographyFontSizeMd) and shadows (lightElevation1) No
Components Sizes for one part of one component, such as the corner radius of a message bubble (messageBubbleRadiusGroupTop) No
Semantics Colors for a role, such as accentPrimary, textPrimary and backgroundCoreApp, and the colors of one kind of component, such as chatBgOutgoing Yes, as theme.semantics

The foundations, the primitives and the component tokens aren't exported. The components import them as constants, so they don't change with the theme. To change the spacing, radius or size of one part, set its component style in the theme, or replace the component.

A semantic token holds a color, or points at another token. A pointer is either a foundation color, resolved when the SDK loads, or a $ reference to another semantic token, such as accentPrimary: "$brand500". The SDK resolves the $ references each time it builds the theme. The brand and chrome scales are semantic tokens too. The brand scale, brand50 to brand900, carries the accent hue, and the chrome scale, chrome0 to chrome1000, carries the neutrals of text, backgrounds and borders.

Light and dark

The semantic tokens have a light and a dark set, with the same 209 names. The SDK picks the set by the color scheme useColorScheme() returns, and builds the theme again when the scheme changes. The foundations, the primitives and the component tokens are the same in both schemes.

The dark scheme flips mostly through the two scales. textPrimary points at chrome900 in both schemes. In the light scheme chrome900 is slate900, #1a1b25. In the dark scheme it's neutral50, #f8f8f8. The brand scale runs in reverse in the dark scheme, and a few tokens point at a different step, such as accentPrimary, which is brand500 in the light scheme and brand400 in the dark one.

Platforms

The tokens are generated for each platform. The semantic tokens are the same on iOS and Android. These differ:

  • The type sizes follow each platform's scale. For example, typographyFontSizeMd is 17 on iOS and 16 on Android.
  • The shadows, lightElevation1 to darkElevation4, are tuned for each platform. On Android the shadow color carries the opacity, and elevation draws the shadow.
  • deviceRadius, deviceSafeAreaTop and deviceSafeAreaBottom differ too. No component reads them.

The font family tokens, such as typographyFontFamilySans, hold the design file's font names, in quotes. No component reads them, and the components set no font family. See Fonts.

Where the tokens come from

The tokens are generated from Stream's design files, and the SDK keeps them in package/src/theme/generated/ in its repository, one file per scheme and platform:

File Contains
light/StreamTokens.ios.ts Every tier, with the light semantic tokens, for iOS
light/StreamTokens.android.ts Every tier, with the light semantic tokens, for Android
light/StreamTokens.web.ts Every tier, with the light semantic tokens, for the web
dark/StreamTokens.{ios,android,web}.ts The same, with the dark semantic tokens
{light,dark}/StreamTokens.ts Re-exports the .web file, so TypeScript can resolve the module
StreamTokens.types.ts The types of every tier

Metro picks the .ios.ts or .android.ts file of the platform it builds for. The SDK reads the foundations, the primitives and the component tokens from the light files, which hold the same values as the dark ones.

The files are never edited by hand. package/sync-theme.sh copies them from the build output of the design tokens and formats them.

Overriding a semantic token

Set the token under semantics in your theme:

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

export const theme: DeepPartial<Theme> = {
  semantics: {
    accentPrimary: "#6d28d9",
    badgeBgPrimary: "#6d28d9",
    buttonPrimaryBg: "#6d28d9",
    buttonPrimaryText: "#6d28d9",
    chatTextMention: "#6d28d9",
  },
};

The SDK resolves the default tokens before it merges your theme. A token you set changes the components that read it, and nothing else. The tokens that point at it keep their default values, which is why the example sets badgeBgPrimary, buttonPrimaryBg, buttonPrimaryText and chatTextMention next to accentPrimary. Tokens that point at another token lists them. Three more things to know:

  • A $ reference in your theme isn't resolved. "$brand500" stays that string and renders as an invalid color, so write the color itself.
  • A token no component reads changes nothing when you set it. The tables mark these tokens. They include the brand and chrome scales, so setting brand500 doesn't recolor the accent.
  • Your semantics apply to whichever scheme is active. To use different values in each scheme, pick the theme by the scheme, as Light and dark shows.

To color your own components with the tokens, read them from useTheme().theme.semantics, where every reference is resolved.

Reading the tables

  • Light and Dark are the token's values in each scheme. When the token points at another token, the table names that token, with a $ for a semantic token, and the value it resolves to is in brackets.
  • iOS and Android are the values on each platform, named the same way.
  • Read by components is "no" when no component reads the token. Setting such a semantic token has no effect.

Semantic tokens

The 209 tokens of theme.semantics, by group. No component reads 86 of them.

Accent

Token Light Dark Read by components
accentError red500 (#d90d10) red400 (#fc526a) yes
accentNeutral $chrome500 (#687385) $chrome500 (#ababab) yes
accentPrimary $brand500 (#005fff) $brand400 (#4586ff) yes
accentSuccess green400 (#00a46e) green300 (#00c384) yes
accentWarning yellow400 (#f26d10) yellow300 (#fa922b) no

Avatar

Token Light Dark Read by components
avatarBgDefault $avatarPaletteBg1 (#c3d9ff) $avatarPaletteBg1 (#1b53bd) no
avatarBgPlaceholder $chrome150 (#d5dbe1) $chrome150 (#464646) yes
avatarPaletteBg1 blue150 (#c3d9ff) blue600 (#1b53bd) yes
avatarPaletteBg2 cyan150 (#a9e4ea) cyan600 (#006970) yes
avatarPaletteBg3 green150 (#8febbd) green600 (#006643) yes
avatarPaletteBg4 purple150 (#d4d7ff) purple600 (#553bd8) yes
avatarPaletteBg5 yellow150 (#fcd579) yellow600 (#a82c00) yes
avatarPaletteText1 blue900 (#091a3b) blue100 (#e3edff) yes
avatarPaletteText2 cyan900 (#002124) cyan100 (#d1f3f6) yes
avatarPaletteText3 green900 (#002213) green100 (#bdfcdb) yes
avatarPaletteText4 purple900 (#1a114d) purple100 (#ecedff) yes
avatarPaletteText5 yellow900 (#331302) yellow100 (#fcedb9) yes
avatarPresenceBgOffline $accentNeutral (#687385) $accentNeutral (#ababab) no
avatarPresenceBgOnline $accentSuccess (#00a46e) $accentSuccess (#00c384) no
avatarPresenceBorder $borderCoreOnInverse (#ffffff) $borderCoreOnInverse (#000000) no
avatarTextDefault $avatarPaletteText1 (#091a3b) $avatarPaletteText1 (#e3edff) no
avatarTextPlaceholder $chrome500 (#687385) $chrome500 (#ababab) yes

Background

Token Light Dark Read by components
backgroundCoreApp $chrome0 (#ffffff) $chrome0 (#000000) yes
backgroundCoreElevation0 $chrome0 (#ffffff) $chrome0 (#000000) yes
backgroundCoreElevation1 $chrome0 (#ffffff) $chrome50 (#1c1c1c) yes
backgroundCoreElevation2 $chrome0 (#ffffff) $chrome100 (#323232) yes
backgroundCoreElevation3 $chrome0 (#ffffff) $chrome200 (#565656) no
backgroundCoreHighlight yellow50 (#fef9da) yellow800 (#5f1a05) yes
backgroundCoreInverse $chrome1000 (#000000) $chrome1000 (#ffffff) yes
backgroundCoreOnAccent $chrome0 (#ffffff) $chrome1000 (#ffffff) no
backgroundCoreOverlayDark rgba(26, 27, 37, 0.25) rgba(0, 0, 0, 0.5) yes
backgroundCoreOverlayLight rgba(255, 255, 255, 0.75) rgba(0, 0, 0, 0.75) yes
backgroundCoreScrim rgba(26, 27, 37, 0.5) rgba(0, 0, 0, 0.75) yes
backgroundCoreSurfaceCard $chrome50 (#f6f8fa) $chrome100 (#323232) yes
backgroundCoreSurfaceDefault $chrome100 (#ebeef1) $chrome100 (#323232) yes
backgroundCoreSurfaceStrong $chrome150 (#d5dbe1) $chrome150 (#464646) yes
backgroundCoreSurfaceSubtle $chrome50 (#f6f8fa) $chrome50 (#1c1c1c) yes
backgroundUtilityDisabled $chrome100 (#ebeef1) $chrome100 (#323232) yes
backgroundUtilityHover rgba(26, 27, 37, 0.1) rgba(255, 255, 255, 0.15) no
backgroundUtilityPressed rgba(26, 27, 37, 0.15) rgba(255, 255, 255, 0.2) yes
backgroundUtilitySelected rgba(26, 27, 37, 0.2) rgba(255, 255, 255, 0.25) yes

Badge

Token Light Dark Read by components
badgeBgDefault $backgroundCoreElevation3 (#ffffff) $backgroundCoreElevation3 (#565656) yes
badgeBgError $accentError (#d90d10) $accentError (#fc526a) yes
badgeBgInverse $chrome1000 (#000000) $chrome1000 (#ffffff) yes
badgeBgNeutral $accentNeutral (#687385) $accentNeutral (#ababab) yes
badgeBgOverlay rgba(0, 0, 0, 0.75) rgba(0, 0, 0, 0.75) yes
badgeBgPrimary $accentPrimary (#005fff) $accentPrimary (#4586ff) yes
badgeBorder $borderCoreOnInverse (#ffffff) $borderCoreOnInverse (#000000) yes
badgeText $textPrimary (#1a1b25) $textPrimary (#f8f8f8) yes
badgeTextOnAccent $textOnAccent (#ffffff) $textOnAccent (#ffffff) yes
badgeTextOnInverse $textOnInverse (#ffffff) $textOnInverse (#000000) yes

Border

Token Light Dark Read by components
borderCoreDefault $chrome150 (#d5dbe1) $chrome200 (#565656) yes
borderCoreInverse $chrome0 (#ffffff) $chrome0 (#000000) yes
borderCoreOnAccent $chrome0 (#ffffff) $chrome1000 (#ffffff) yes
borderCoreOnInverse $chrome0 (#ffffff) $chrome0 (#000000) no
borderCoreOnSurface $chrome300 (#a3acba) $chrome300 (#6a6a6a) yes
borderCoreOpacityStrong rgba(26, 27, 37, 0.25) rgba(255, 255, 255, 0.25) no
borderCoreOpacitySubtle rgba(26, 27, 37, 0.1) rgba(255, 255, 255, 0.2) yes
borderCoreStrong $chrome300 (#a3acba) $chrome300 (#6a6a6a) yes
borderCoreSubtle $chrome100 (#ebeef1) $chrome100 (#323232) yes
borderUtilityActive $accentPrimary (#005fff) $accentPrimary (#4586ff) yes
borderUtilityDisabled $chrome100 (#ebeef1) $chrome100 (#323232) yes
borderUtilityDisabledOnSurface $chrome150 (#d5dbe1) $chrome150 (#464646) yes
borderUtilityError $accentError (#d90d10) $accentError (#fc526a) no
borderUtilityFocused $brand150 (#c3d9ff) $brand150 (#19418d) no
borderUtilityHover rgba(26, 27, 37, 0.1) rgba(255, 255, 255, 0.1) no
borderUtilityPressed rgba(26, 27, 37, 0.2) rgba(255, 255, 255, 0.2) no
borderUtilitySelected rgba(26, 27, 37, 0.15) rgba(255, 255, 255, 0.15) no
borderUtilitySuccess $accentSuccess (#00a46e) $accentSuccess (#00c384) no
borderUtilityWarning $accentWarning (#f26d10) $accentWarning (#fa922b) no

Brand scale

Token Light Dark Read by components
brand50 blue50 (#f3f7ff) blue900 (#091a3b) no
brand100 blue100 (#e3edff) blue800 (#142f63) no
brand150 blue150 (#c3d9ff) blue700 (#19418d) yes
brand200 blue200 (#a5c5ff) blue600 (#1b53bd) no
brand300 blue300 (#78a8ff) blue500 (#005fff) no
brand400 blue400 (#4586ff) blue400 (#4586ff) no
brand500 blue500 (#005fff) blue300 (#78a8ff) no
brand600 blue600 (#1b53bd) blue200 (#a5c5ff) no
brand700 blue700 (#19418d) blue150 (#c3d9ff) no
brand800 blue800 (#142f63) blue100 (#e3edff) no
brand900 blue900 (#091a3b) blue50 (#f3f7ff) yes

Button

Token Light Dark Read by components
buttonDestructiveBg $accentError (#d90d10) $accentError (#fc526a) yes
buttonDestructiveBgLiquidGlass $backgroundCoreElevation0 (#ffffff) $backgroundCoreElevation0 (#000000) no
buttonDestructiveBorder $accentError (#d90d10) $accentError (#fc526a) yes
buttonDestructiveBorderOnDark $textOnInverse (#ffffff) $textOnInverse (#000000) no
buttonDestructiveText $accentError (#d90d10) $accentError (#fc526a) yes
buttonDestructiveTextOnAccent $textOnAccent (#ffffff) $textOnAccent (#ffffff) yes
buttonDestructiveTextOnDark $textOnInverse (#ffffff) $textOnInverse (#000000) no
buttonPrimaryBg $accentPrimary (#005fff) $accentPrimary (#4586ff) yes
buttonPrimaryBgLiquidGlass baseTransparent0 (rgba(255, 255, 255, 0)) baseTransparent0 (rgba(255, 255, 255, 0)) no
buttonPrimaryBorder $brand200 (#a5c5ff) $brand200 (#1b53bd) yes
buttonPrimaryBorderOnDark $borderCoreOnInverse (#ffffff) $borderCoreOnInverse (#000000) no
buttonPrimaryText $accentPrimary (#005fff) $accentPrimary (#4586ff) yes
buttonPrimaryTextOnAccent $textOnAccent (#ffffff) $textOnAccent (#ffffff) yes
buttonPrimaryTextOnDark $textOnInverse (#ffffff) $textOnInverse (#000000) no
buttonSecondaryBg $backgroundCoreSurfaceDefault (#ebeef1) $backgroundCoreSurfaceDefault (#323232) yes
buttonSecondaryBgLiquidGlass $backgroundCoreElevation0 (#ffffff) $backgroundCoreElevation0 (#000000) no
buttonSecondaryBorder $borderCoreDefault (#d5dbe1) $borderCoreDefault (#565656) yes
buttonSecondaryBorderOnDark $borderCoreOnInverse (#ffffff) $borderCoreOnInverse (#000000) no
buttonSecondaryText $textPrimary (#1a1b25) $textPrimary (#f8f8f8) yes
buttonSecondaryTextOnAccent $textPrimary (#1a1b25) $textPrimary (#f8f8f8) yes
buttonSecondaryTextOnDark $textOnInverse (#ffffff) $textOnInverse (#000000) no

Chat

Token Light Dark Read by components
chatBgAttachmentIncoming $backgroundCoreSurfaceStrong (#d5dbe1) $backgroundCoreSurfaceStrong (#464646) yes
chatBgAttachmentOutgoing $brand150 (#c3d9ff) $brand150 (#19418d) yes
chatBgIncoming $backgroundCoreSurfaceDefault (#ebeef1) $backgroundCoreSurfaceDefault (#323232) yes
chatBgMention baseTransparent0 (rgba(255, 255, 255, 0)) baseTransparent0 (rgba(255, 255, 255, 0)) no
chatBgMentionBroadcast $chatBgMention (rgba(255, 255, 255, 0)) $chatBgMention (rgba(255, 255, 255, 0)) no
chatBgMentionGroup $chatBgMention (rgba(255, 255, 255, 0)) $chatBgMention (rgba(255, 255, 255, 0)) no
chatBgMentionRole $chatBgMention (rgba(255, 255, 255, 0)) $chatBgMention (rgba(255, 255, 255, 0)) no
chatBgMentionUser $chatBgMention (rgba(255, 255, 255, 0)) $chatBgMention (rgba(255, 255, 255, 0)) no
chatBgOutgoing $brand100 (#e3edff) $brand100 (#142f63) yes
chatBorderIncoming $borderCoreSubtle (#ebeef1) $borderCoreSubtle (#323232) no
chatBorderOnChatIncoming $borderCoreStrong (#a3acba) $borderCoreStrong (#6a6a6a) yes
chatBorderOnChatOutgoing $brand300 (#78a8ff) $brand300 (#005fff) yes
chatBorderOutgoing $brand100 (#e3edff) $brand100 (#142f63) no
chatPollProgressFillIncoming $controlProgressBarFill (#687385) $controlProgressBarFill (#ababab) yes
chatPollProgressFillOutgoing $accentPrimary (#005fff) $accentPrimary (#4586ff) yes
chatPollProgressTrackIncoming $controlProgressBarTrack (#d5dbe1) $controlProgressBarTrack (#464646) yes
chatPollProgressTrackOutgoing $brand200 (#a5c5ff) $brand200 (#1b53bd) yes
chatReplyIndicatorIncoming $chrome400 (#87909f) $chrome400 (#8f8f8f) yes
chatReplyIndicatorOutgoing $brand400 (#4586ff) $brand400 (#4586ff) yes
chatTextIncoming $textPrimary (#1a1b25) $textPrimary (#f8f8f8) yes
chatTextLink $textLink (#005fff) $textLink (#a5c5ff) no
chatTextMention $accentPrimary (#005fff) $accentPrimary (#4586ff) yes
chatTextMentionBroadcast $chatTextMention (#005fff) $chatTextMention (#4586ff) yes
chatTextMentionGroup $chatTextMention (#005fff) $chatTextMention (#4586ff) yes
chatTextMentionRole $chatTextMention (#005fff) $chatTextMention (#4586ff) yes
chatTextMentionUser $chatTextMention (#005fff) $chatTextMention (#4586ff) yes
chatTextOutgoing $brand900 (#091a3b) $brand900 (#f3f7ff) yes
chatTextReaction $textSecondary (#414552) $textSecondary (#d8d8d8) no
chatTextRead $accentPrimary (#005fff) $accentPrimary (#4586ff) no
chatTextSystem $textSecondary (#414552) $textSecondary (#d8d8d8) yes
chatTextTimestamp $textTertiary (#687385) $textTertiary (#ababab) yes
chatTextTypingIndicator $chatTextIncoming (#1a1b25) $chatTextIncoming (#f8f8f8) yes
chatTextUsername $textSecondary (#414552) $textSecondary (#d8d8d8) yes
chatThreadConnectorIncoming $borderCoreDefault (#d5dbe1) $borderCoreDefault (#565656) yes
chatThreadConnectorOutgoing $brand150 (#c3d9ff) $brand150 (#19418d) yes
chatWaveformBar $borderCoreOpacityStrong (rgba(26, 27, 37, 0.25)) $borderCoreOpacityStrong (rgba(255, 255, 255, 0.25)) yes
chatWaveformBarPlaying $accentPrimary (#005fff) $accentPrimary (#4586ff) yes

Chrome scale

Token Light Dark Read by components
chrome0 baseWhite (#ffffff) baseBlack (#000000) no
chrome50 slate50 (#f6f8fa) neutral900 (#1c1c1c) no
chrome100 slate100 (#ebeef1) neutral800 (#323232) no
chrome150 slate150 (#d5dbe1) neutral700 (#464646) no
chrome200 slate200 (#c0c8d2) neutral600 (#565656) no
chrome300 slate300 (#a3acba) neutral500 (#6a6a6a) no
chrome400 slate400 (#87909f) neutral400 (#8f8f8f) no
chrome500 slate500 (#687385) neutral300 (#ababab) no
chrome600 slate600 (#545969) neutral200 (#c4c4c4) no
chrome700 slate700 (#414552) neutral150 (#d8d8d8) no
chrome800 slate800 (#30313d) neutral100 (#efefef) no
chrome900 slate900 (#1a1b25) neutral50 (#f8f8f8) no
chrome1000 baseBlack (#000000) baseWhite (#ffffff) no

Controls

Token Light Dark Read by components
controlCheckboxBg baseTransparent0 (rgba(255, 255, 255, 0)) baseTransparent0 (rgba(255, 255, 255, 0)) no
controlCheckboxBgSelected $accentPrimary (#005fff) $accentPrimary (#4586ff) no
controlCheckboxBorder $borderCoreDefault (#d5dbe1) $borderCoreDefault (#565656) no
controlCheckboxIcon $textOnAccent (#ffffff) $textOnAccent (#ffffff) no
controlChipBorder $borderCoreDefault (#d5dbe1) $borderCoreDefault (#565656) no
controlChipText $textPrimary (#1a1b25) $textPrimary (#f8f8f8) no
controlPlayButtonBg rgba(0, 0, 0, 0.75) rgba(0, 0, 0, 0.75) yes
controlPlayButtonIcon $textOnAccent (#ffffff) $textOnAccent (#ffffff) yes
controlPlaybackThumbBgActive $accentPrimary (#005fff) $accentPrimary (#4586ff) no
controlPlaybackThumbBgDefault $backgroundCoreOnAccent (#ffffff) $backgroundCoreOnAccent (#ffffff) no
controlPlaybackThumbBorderActive $borderCoreOnAccent (#ffffff) $borderCoreOnAccent (#ffffff) no
controlPlaybackThumbBorderDefault $borderCoreOpacityStrong (rgba(26, 27, 37, 0.25)) $borderCoreOpacityStrong (rgba(255, 255, 255, 0.25)) no
controlPlaybackToggleBorder $borderCoreDefault (#d5dbe1) $borderCoreDefault (#565656) yes
controlPlaybackToggleText $textPrimary (#1a1b25) $textPrimary (#f8f8f8) yes
controlProgressBarFill $accentNeutral (#687385) $accentNeutral (#ababab) no
controlProgressBarTrack $backgroundCoreSurfaceStrong (#d5dbe1) $backgroundCoreSurfaceStrong (#464646) no
controlRadioButtonBg baseTransparent0 (rgba(255, 255, 255, 0)) baseTransparent0 (rgba(255, 255, 255, 0)) no
controlRadioButtonBgSelected $accentPrimary (#005fff) $accentPrimary (#4586ff) no
controlRadioButtonBorder $borderCoreDefault (#d5dbe1) $borderCoreDefault (#565656) no
controlRadioButtonIndicator $textOnAccent (#ffffff) $textOnAccent (#ffffff) no
controlRadioCheckBg baseTransparent0 (rgba(255, 255, 255, 0)) baseTransparent0 (rgba(255, 255, 255, 0)) no
controlRadioCheckBgSelected $accentPrimary (#005fff) $accentPrimary (#4586ff) yes
controlRadioCheckBorder $borderCoreDefault (#d5dbe1) $borderCoreDefault (#565656) yes
controlRadioCheckIcon $textOnAccent (#ffffff) $textOnAccent (#ffffff) yes
controlRemoveControlBg $backgroundCoreInverse (#000000) $backgroundCoreInverse (#ffffff) yes
controlRemoveControlBorder $borderCoreOnInverse (#ffffff) $borderCoreOnInverse (#000000) yes
controlRemoveControlIcon $textOnInverse (#ffffff) $textOnInverse (#000000) yes
controlToggleSwitchBg $accentNeutral (#687385) $accentNeutral (#ababab) yes
controlToggleSwitchBgDisabled $backgroundUtilityDisabled (#ebeef1) $backgroundUtilityDisabled (#323232) no
controlToggleSwitchBgSelected $accentPrimary (#005fff) $accentPrimary (#4586ff) yes
controlToggleSwitchKnob $backgroundCoreOnAccent (#ffffff) $backgroundCoreOnAccent (#ffffff) yes

Input

Token Light Dark Read by components
inputSendIcon $accentPrimary (#005fff) $accentPrimary (#4586ff) no
inputSendIconDisabled $textDisabled (#a3acba) $textDisabled (#6a6a6a) no
inputTextDefault $textPrimary (#1a1b25) $textPrimary (#f8f8f8) yes
inputTextDisabled $textDisabled (#a3acba) $textDisabled (#6a6a6a) no
inputTextIcon $textTertiary (#687385) $textTertiary (#ababab) yes
inputTextPlaceholder $textTertiary (#687385) $textTertiary (#ababab) yes

Presence

Token Light Dark Read by components
presenceBgOffline $accentNeutral (#687385) $accentNeutral (#ababab) yes
presenceBgOnline $accentSuccess (#00a46e) $accentSuccess (#00c384) yes
presenceBorder $borderCoreInverse (#ffffff) $borderCoreInverse (#000000) yes

Reaction

Token Light Dark Read by components
reactionBg $backgroundCoreElevation3 (#ffffff) $backgroundCoreElevation3 (#565656) yes
reactionBorder $borderCoreDefault (#d5dbe1) $borderCoreDefault (#565656) yes
reactionEmoji $textPrimary (#1a1b25) $textPrimary (#f8f8f8) no
reactionText $textPrimary (#1a1b25) $textPrimary (#f8f8f8) yes

Skeleton

Token Light Dark Read by components
skeletonLoadingBase baseTransparent0 (rgba(255, 255, 255, 0)) baseTransparent0 (rgba(255, 255, 255, 0)) no
skeletonLoadingHighlight $backgroundCoreOverlayLight (rgba(255, 255, 255, 0.75)) $backgroundCoreOverlayLight (rgba(0, 0, 0, 0.75)) yes

System

Token Light Dark Read by components
systemBgBlur rgba(255, 255, 255, 0.01) rgba(0, 0, 0, 0.01) no
systemCaret $accentPrimary (#005fff) $accentPrimary (#4586ff) no
systemScrollbar rgba(0, 0, 0, 0.5) rgba(255, 255, 255, 0.5) no
systemText $chrome1000 (#000000) $chrome1000 (#ffffff) no

Text

Token Light Dark Read by components
textDisabled $chrome300 (#a3acba) $chrome300 (#6a6a6a) yes
textLink $brand500 (#005fff) $brand600 (#a5c5ff) yes
textOnAccent $chrome0 (#ffffff) $chrome1000 (#ffffff) yes
textOnInverse $chrome0 (#ffffff) $chrome0 (#000000) yes
textPrimary $chrome900 (#1a1b25) $chrome900 (#f8f8f8) yes
textSecondary $chrome700 (#414552) $chrome700 (#d8d8d8) yes
textTertiary $chrome500 (#687385) $chrome500 (#ababab) yes

Tokens that point at another token

Each row lists the semantic tokens whose default points at a token with a $ reference. Setting the token in the first column doesn't change them, so set the ones you want to follow it. The rows hold for both schemes. The brand and chrome scales are left out, because the tokens that point at a step of them differ between the schemes. The tables above show those.

Token Tokens that point at it
accentError badgeBgError, borderUtilityError, buttonDestructiveBg, buttonDestructiveBorder, buttonDestructiveText
accentNeutral avatarPresenceBgOffline, badgeBgNeutral, controlProgressBarFill, controlToggleSwitchBg, presenceBgOffline
accentPrimary badgeBgPrimary, borderUtilityActive, buttonPrimaryBg, buttonPrimaryText, chatPollProgressFillOutgoing, chatTextMention, chatTextRead, chatWaveformBarPlaying, controlCheckboxBgSelected, controlPlaybackThumbBgActive, controlRadioButtonBgSelected, controlRadioCheckBgSelected, controlToggleSwitchBgSelected, inputSendIcon, systemCaret
accentSuccess avatarPresenceBgOnline, borderUtilitySuccess, presenceBgOnline
accentWarning borderUtilityWarning
avatarPaletteBg1 avatarBgDefault
avatarPaletteText1 avatarTextDefault
backgroundCoreElevation0 buttonDestructiveBgLiquidGlass, buttonSecondaryBgLiquidGlass
backgroundCoreElevation3 badgeBgDefault, reactionBg
backgroundCoreInverse controlRemoveControlBg
backgroundCoreOnAccent controlPlaybackThumbBgDefault, controlToggleSwitchKnob
backgroundCoreOverlayLight skeletonLoadingHighlight
backgroundCoreSurfaceDefault buttonSecondaryBg, chatBgIncoming
backgroundCoreSurfaceStrong chatBgAttachmentIncoming, controlProgressBarTrack
backgroundUtilityDisabled controlToggleSwitchBgDisabled
borderCoreDefault buttonSecondaryBorder, chatThreadConnectorIncoming, controlCheckboxBorder, controlChipBorder, controlPlaybackToggleBorder, controlRadioButtonBorder, controlRadioCheckBorder, reactionBorder
borderCoreInverse presenceBorder
borderCoreOnAccent controlPlaybackThumbBorderActive
borderCoreOnInverse avatarPresenceBorder, badgeBorder, buttonPrimaryBorderOnDark, buttonSecondaryBorderOnDark, controlRemoveControlBorder
borderCoreOpacityStrong chatWaveformBar, controlPlaybackThumbBorderDefault
borderCoreStrong chatBorderOnChatIncoming
borderCoreSubtle chatBorderIncoming
chatBgMention chatBgMentionBroadcast, chatBgMentionGroup, chatBgMentionRole, chatBgMentionUser
chatTextIncoming chatTextTypingIndicator
chatTextMention chatTextMentionBroadcast, chatTextMentionGroup, chatTextMentionRole, chatTextMentionUser
controlProgressBarFill chatPollProgressFillIncoming
controlProgressBarTrack chatPollProgressTrackIncoming
textDisabled inputSendIconDisabled, inputTextDisabled
textLink chatTextLink
textOnAccent badgeTextOnAccent, buttonDestructiveTextOnAccent, buttonPrimaryTextOnAccent, controlCheckboxIcon, controlPlayButtonIcon, controlRadioButtonIndicator, controlRadioCheckIcon
textOnInverse badgeTextOnInverse, buttonDestructiveBorderOnDark, buttonDestructiveTextOnDark, buttonPrimaryTextOnDark, buttonSecondaryTextOnDark, controlRemoveControlIcon
textPrimary badgeText, buttonSecondaryText, buttonSecondaryTextOnAccent, chatTextIncoming, controlChipText, controlPlaybackToggleText, inputTextDefault, reactionEmoji, reactionText
textSecondary chatTextReaction, chatTextSystem, chatTextUsername
textTertiary chatTextTimestamp, inputTextIcon, inputTextPlaceholder

Primitives

The primitives aren't part of the theme.

Token iOS Android Read by components
darkElevation1 elevation 2, offset 1, radius 3, opacity 0.2, color rgb(0,0,0) elevation 2, offset 1.49, radius 3.69, opacity 1, color rgba(0,0,0,0.42) no
darkElevation2 elevation 3, offset 2, radius 6, opacity 0.22, color rgb(0,0,0) elevation 3, offset 2, radius 5.63, opacity 1, color rgba(0,0,0,0.44) no
darkElevation3 elevation 6, offset 4, radius 12, opacity 0.24, color rgb(0,0,0) elevation 6, offset 3.49, radius 11.08, opacity 1, color rgba(0,0,0,0.46) yes
darkElevation4 elevation 12, offset 8, radius 24, opacity 0.28, color rgb(0,0,0) elevation 8, offset 5.38, radius 16.89, opacity 1, color rgba(0,0,0,0.51) no
lightElevation1 elevation 2, offset 1, radius 3, opacity 0.12, color rgb(0,0,0) elevation 1, offset 1, radius 2.83, opacity 1, color rgba(0,0,0,0.29) yes
lightElevation2 elevation 3, offset 2, radius 6, opacity 0.14, color rgb(0,0,0) elevation 3, offset 2, radius 5.68, opacity 1, color rgba(0,0,0,0.31) yes
lightElevation3 elevation 6, offset 4, radius 12, opacity 0.16, color rgb(0,0,0) elevation 6, offset 3.5, radius 11.1, opacity 1, color rgba(0,0,0,0.36) yes
lightElevation4 elevation 12, offset 8, radius 24, opacity 0.2, color rgb(0,0,0) elevation 8, offset 5.4, radius 16.92, opacity 1, color rgba(0,0,0,0.40) yes
radius2xl radius20 (20) radius20 (20) no
radius3xl radius24 (24) radius24 (24) yes
radius4xl radius32 (32) radius32 (32) yes
radiusLg radius12 (12) radius12 (12) yes
radiusMax radiusFull (9999) radiusFull (9999) yes
radiusMd radius8 (8) radius8 (8) yes
radiusNone radius0 (0) radius0 (0) yes
radiusSm radius6 (6) radius6 (6) yes
radiusXl radius16 (16) radius16 (16) yes
radiusXs radius4 (4) radius4 (4) no
radiusXxs radius2 (2) radius2 (2) yes
spacing2xl space32 (32) space32 (32) yes
spacing3xl space40 (40) space40 (40) yes
spacingLg space20 (20) space20 (20) yes
spacingMd space16 (16) space16 (16) yes
spacingNone space0 (0) space0 (0) no
spacingSm space12 (12) space12 (12) yes
spacingXl space24 (24) space24 (24) yes
spacingXs space8 (8) space8 (8) yes
spacingXxs space4 (4) space4 (4) yes
spacingXxxs space2 (2) space2 (2) yes
typographyFontFamilyMono fontFamilySfMono ("SF Mono") fontFamilyRobotoMono ("Roboto Mono") no
typographyFontFamilySans fontFamilySfPro ("SF Pro") fontFamilyRoboto ("Roboto") no
typographyFontSize2xl fontSizeSize24 (24) fontSizeSize24 (24) yes
typographyFontSizeLg fontSizeSize20 (20) fontSizeSize18 (18) yes
typographyFontSizeMd fontSizeSize17 (17) fontSizeSize16 (16) yes
typographyFontSizeMicro fontSizeSize8 (8) fontSizeSize8 (8) no
typographyFontSizeSm fontSizeSize15 (15) fontSizeSize14 (14) yes
typographyFontSizeXl fontSizeSize22 (22) fontSizeSize20 (20) yes
typographyFontSizeXs fontSizeSize13 (13) fontSizeSize12 (12) yes
typographyFontSizeXxs fontSizeSize12 (12) fontSizeSize10 (10) yes
typographyFontWeightBold 700 700 yes
typographyFontWeightMedium 500 500 yes
typographyFontWeightRegular 400 400 yes
typographyFontWeightSemiBold 600 600 yes
typographyLineHeightNormal lineHeightLineHeight20 (20) lineHeightLineHeight20 (20) yes
typographyLineHeightRelaxed lineHeightLineHeight24 (24) lineHeightLineHeight24 (24) yes
typographyLineHeightTight lineHeightLineHeight16 (16) lineHeightLineHeight16 (16) yes

Component tokens

The component tokens aren't part of the theme.

Token iOS Android Read by components
buttonHitTargetMinHeight size48 (48) size48 (48) yes
buttonHitTargetMinWidth size48 (48) size48 (48) no
buttonPaddingXIconOnlyLg 14 14 no
buttonPaddingXIconOnlyMd 10 10 yes
buttonPaddingXIconOnlySm 6 6 no
buttonPaddingXIconOnlyXs 4 4 no
buttonPaddingXWithLabelLg 16 16 no
buttonPaddingXWithLabelMd 16 16 no
buttonPaddingXWithLabelSm 16 16 no
buttonPaddingXWithLabelXs 12 12 no
buttonPaddingYLg 14 14 no
buttonPaddingYMd 10 10 no
buttonPaddingYSm 6 6 no
buttonPaddingYXs 4 4 no
buttonRadiusFull radiusFull (9999) radiusFull (9999) no
buttonRadiusLg radiusFull (9999) radiusFull (9999) no
buttonRadiusMd radiusFull (9999) radiusFull (9999) no
buttonRadiusSm radiusFull (9999) radiusFull (9999) no
buttonVisualHeightLg size48 (48) size48 (48) no
buttonVisualHeightMd size40 (40) size40 (40) no
buttonVisualHeightSm size32 (32) size32 (32) no
buttonVisualHeightXs size24 (24) size24 (24) no
composerRadiusFixed radius3xl (24) radius3xl (24) no
composerRadiusFloating radius3xl (24) radius3xl (24) no
deviceRadius 62 radius4xl (32) no
deviceSafeAreaBottom space32 (32) space40 (40) no
deviceSafeAreaTop 50 52 no
emoji2xl fontSizeSize64 (64) fontSizeSize64 (64) no
emojiLg fontSizeSize32 (32) fontSizeSize32 (32) no
emojiMd fontSizeSize24 (24) fontSizeSize24 (24) no
emojiSm typographyFontSizeMd (17) typographyFontSizeMd (16) no
emojiXl fontSizeSize48 (48) fontSizeSize48 (48) no
iconSizeLg size32 (32) size32 (32) no
iconSizeMd size20 (20) size20 (20) no
iconSizeSm size16 (16) size16 (16) no
iconSizeXs size12 (12) size12 (12) no
iconStrokeDefault w150 (1.5) w150 (1.5) no
iconStrokeEmphasis w200 (2) w200 (2) no
iconStrokeSubtle w120 (1.2) w120 (1.2) no
messageBubbleRadiusAttachment radiusLg (12) radiusLg (12) yes
messageBubbleRadiusAttachmentInline radiusMd (8) radiusMd (8) no
messageBubbleRadiusGroupBottom radius2xl (20) radius2xl (20) yes
messageBubbleRadiusGroupMiddle radius2xl (20) radius2xl (20) no
messageBubbleRadiusGroupTop radius2xl (20) radius2xl (20) no
messageBubbleRadiusTail radiusNone (0) radiusNone (0) yes

Foundations

The foundations aren't part of the theme, and no component reads them directly. They're the same on both platforms and in both schemes.

Color scales

Each token is the scale name and a step, for example green300.

Scale 50 100 150 200 300 400 500 600 700 800 900
slate #f6f8fa #ebeef1 #d5dbe1 #c0c8d2 #a3acba #87909f #687385 #545969 #414552 #30313d #1a1b25
neutral #f8f8f8 #efefef #d8d8d8 #c4c4c4 #ababab #8f8f8f #6a6a6a #565656 #464646 #323232 #1c1c1c
blue #f3f7ff #e3edff #c3d9ff #a5c5ff #78a8ff #4586ff #005fff #1b53bd #19418d #142f63 #091a3b
cyan #f1fbfc #d1f3f6 #a9e4ea #72d7e0 #45bcc7 #1e9ea9 #248088 #006970 #065056 #003a3f #002124
green #e1ffee #bdfcdb #8febbd #59dea3 #00c384 #00a46e #277e59 #006643 #004f33 #003a25 #002213
purple #f7f8ff #ecedff #d4d7ff #c1c5ff #a1a3ff #8482fc #644af9 #553bd8 #4032a1 #2e2576 #1a114d
yellow #fef9da #fcedb9 #fcd579 #f6bf57 #fa922b #f26d10 #c84801 #a82c00 #842106 #5f1a05 #331302
red #fff5fa #ffe7f2 #ffccdf #ffb1cd #fe87a1 #fc526a #d90d10 #b3093c #890d37 #68052b #3e021a
violet #fef4ff #fbe8fe #f7cffc #eeb5f4 #e68bec #d75fe7 #b716ca #9d00ae #7c0089 #5c0066 #36003d
lime #f1fde8 #d4ffb0 #b1ee79 #9cda5d #78c100 #639e11 #4b7a0a #3e6213 #355315 #203a00 #112100

Base colors

Token Value
baseTransparent0 rgba(255, 255, 255, 0)
baseTransparentWhite10 rgba(255, 255, 255, 0.1)
baseTransparentWhite20 rgba(255, 255, 255, 0.2)
baseTransparentWhite30 rgba(255, 255, 255, 0.3)
baseTransparentWhite70 rgba(255, 255, 255, 0.7)
baseTransparentBlack5 rgba(0, 0, 0, 0.05)
baseTransparentBlack10 rgba(0, 0, 0, 0.1)
baseTransparentBlack70 rgba(0, 0, 0, 0.7)
baseBlack #000000
baseWhite #ffffff

Other foundations

Group Tokens
layout size2 2, size4 4, size6 6, size8 8, size12 12, size16 16, size20 20, size24 24, size28 28, size32 32, size40 40, size48 48, size56 56, size64 64, size80 80, size128 128, size144 144, size208 208, size240 240, size320 320, size480 480, size560 560, size640 640, size760 760
radius radius0 0, radius2 2, radius4 4, radius6 6, radius8 8, radius12 12, radius16 16, radius20 20, radius24 24, radius32 32, radiusFull 9999
spacing space0 0, space2 2, space4 4, space8 8, space12 12, space16 16, space20 20, space24 24, space32 32, space40 40, space48 48, space64 64, space80 80
stroke w100 1, w120 1.2, w150 1.5, w200 2, w300 3, w400 4
typography, font sizes fontSizeSize8 8, fontSizeSize10 10, fontSizeSize11 11, fontSizeSize12 12, fontSizeSize13 13, fontSizeSize14 14, fontSizeSize15 15, fontSizeSize16 16, fontSizeSize17 17, fontSizeSize18 18, fontSizeSize20 20, fontSizeSize22 22, fontSizeSize24 24, fontSizeSize28 28, fontSizeSize32 32, fontSizeSize40 40, fontSizeSize48 48, fontSizeSize64 64
typography, line heights lineHeightLineHeight8 8, lineHeightLineHeight10 10, lineHeightLineHeight12 12, lineHeightLineHeight13 13, lineHeightLineHeight14 14, lineHeightLineHeight15 15, lineHeightLineHeight16 16, lineHeightLineHeight17 17, lineHeightLineHeight18 18, lineHeightLineHeight20 20, lineHeightLineHeight24 24, lineHeightLineHeight28 28, lineHeightLineHeight32 32, lineHeightLineHeight40 40, lineHeightLineHeight48 48
typography, weights fontWeightW400 400, fontWeightW500 500, fontWeightW600 600, fontWeightW700 700
typography, families fontFamilyGeist, fontFamilyGeistMono, fontFamilySfPro, fontFamilySfMono, fontFamilyRoboto, fontFamilyRobotoMono

Best practices

  • Override semantic tokens, not component styles, for colors, and pick the theme by the color scheme to use different colors in each.
  • Set every token the parts you want to change read. A token you set doesn't reach the tokens that point at it.
  • Check both schemes after a change. A token can point at different steps in the light and the dark scheme.
  • Read colors for your own components from useTheme().theme.semantics, so they follow your theme.
  • Don't import the generated files. They aren't part of the public API, and the theme doesn't override them.

The tables on this page are generated by a script that reads package/src/theme/generated/{light,dark}/StreamTokens.{ios,android}.ts in the SDK's repository. It takes what each token points at from the source, and each value from the transpiled module. A token is listed as not read when its name appears nowhere in the SDK's source outside the generated files and tests, except the avatar palette tokens, which the avatars read by index.