Design System
RealtimeKit's UI Kit provides all the necessary UI components to allow complete customization of all its UI Kit components. You can customize your brand colours, fonts, logo and more.
To get started with customizing the design system for your meetings, you need to first integrate RealtimeKit's SDK into your application.
The provideRtkDesignSystem() utility allows you to override the existing design system with your own custom design system.
Each mobile platform exposes a design token system that controls colors, borders, typography, and spacing. You configure tokens before launching a meeting and the UI Kit applies them across all components.
<script type="module"> import { provideRtkDesignSystem } from "https://cdn.jsdelivr.net/npm/@cloudflare/realtimekit-ui@latest/dist/index.js";</script>import { provideRtkDesignSystem } from "@cloudflare/realtimekit-react-ui";import { provideRtkDesignSystem } from "@cloudflare/realtimekit-angular-ui";import RealtimeKitUIimport com.cloudflare.realtimekit.ui.RealtimeKitUIBuilderimport com.cloudflare.realtimekit.ui.RealtimeKitUIInfoimport com.cloudflare.realtimekit.ui.token.*import com.cloudflare.realtimekit.models.RtkMeetingInfoimport 'package:realtimekit_ui/realtimekit_ui.dart';import 'package:flutter/material.dart';import { RtkUIProvider, provideRtkDesignSystem, generateBrandColors, generateBackgroundColors,} from "@cloudflare/realtimekit-react-native-ui";<div id="app"></div>
<script> provideRtkDesignSystem(document.getElementById("app"), { googleFont: "Lobster", // sets light background colors theme: "light", colors: { danger: "#ffac00", brand: { 300: "#00FFE1", 400: "#00FFFF", 500: "#00E1D4", 600: "#007B74", 700: "#00655F", }, text: "#071428", "text-on-brand": "#ffffff", "video-bg": "#E5E7EB", }, borderRadius: "extra-rounded", });</script><div id="app"></div>
<script> provideRtkDesignSystem(document.getElementById("app"), { googleFont: "Lobster", // sets light background colors theme: "light", colors: { danger: "#ffac00", brand: { 300: "#00FFE1", 400: "#00FFFF", 500: "#00E1D4", 600: "#007B74", 700: "#00655F", }, text: "#071428", "text-on-brand": "#ffffff", "video-bg": "#E5E7EB", }, borderRadius: "extra-rounded", });</script>function Example() { const meetingEl = useRef(); const { meeting } = useRealtimeKitMeeting();
useEffect(() => { provideRtkDesignSystem(meetingEl.current, { googleFont: "Lobster", // sets light background colors theme: "light", colors: { danger: "#ffac00", brand: { 300: "#00FFE1", 400: "#00FFFF", 500: "#00E1D4", 600: "#007B74", 700: "#00655F", }, text: "#071428", "text-on-brand": "#ffffff", "video-bg": "#E5E7EB", }, borderRadius: "extra-rounded", }); }, []);
return ( <div style={{ height: "400px" }}> <RtkMeeting meeting={meeting} ref={meetingEl} mode="fill" /> </div> );}Construct an RtkDesignTokens object and pass it to RealtimeKitUIInfo. Then call RealtimeKitUIBuilder.build() to launch the meeting.
import android.graphics.Color
val customColors = RtkColorTokens( brand = BrandColor( shade300 = Color.parseColor("#FF9A6C"), shade400 = Color.parseColor("#FF8552"), shade500 = Color.parseColor("#FF6B35"), shade600 = Color.parseColor("#E55A24"), shade700 = Color.parseColor("#CC4A14"), ), background = BackgroundColor( shade600 = Color.parseColor("#666666"), shade700 = Color.parseColor("#4C4C4C"), shade800 = Color.parseColor("#333333"), shade900 = Color.parseColor("#1A1A1A"), shade1000 = Color.parseColor("#080808"), ), text = TextColor( onBrand = TextColor.TextColorOnBrand( shade1000 = Color.parseColor("#FF111111"), shade900 = Color.parseColor("#E0111111"), shade800 = Color.parseColor("#C2111111"), shade700 = Color.parseColor("#A3111111"), shade600 = Color.parseColor("#85111111"), ), onBackground = TextColor.TextColorOnBackground( shade1000 = Color.parseColor("#FFFFFFFF"), shade900 = Color.parseColor("#E0FFFFFF"), shade800 = Color.parseColor("#C2FFFFFF"), shade700 = Color.parseColor("#A3FFFFFF"), shade600 = Color.parseColor("#85FFFFFF"), ), ),)
val designTokens = RtkDesignTokens( colors = customColors, borderRadius = RtkBorderRadiusToken.Rounded, borderWidth = RtkBorderWidthToken.Thin,)
val uiKitInfo = RealtimeKitUIInfo( activity = this, rtkMeetingInfo = RtkMeetingInfo(authToken = "<auth_token>"), designTokens = designTokens,)RealtimeKitUIBuilder.build(uiKitInfo).startMeeting()Construct an RtkDesignTokens object and pass it to RealtimeKitUIInfo via the designToken parameter.
Flutter supports two approaches for color configuration:
- Simple — provide a single base color and the SDK auto-generates all shades
- Advanced — provide an explicit
RtkColorSwatchwith all shade values
Simple color configuration:
final designTokens = RtkDesignTokens( colorToken: RtkColorToken( backgroundColor: const Color(0xFF0B0B0B), brandColor: const Color(0xFFF17F1F), textOnBrand: Colors.white, textOnBackground: Colors.white, ), borderRadius: RtkBorderRadius.rounded, borderWidth: RtkBorderWidth.none,);
final uiKitInfo = RealtimeKitUIInfo(meetingInfo, designToken: designTokens);final rtkUI = RealtimeKitUIBuilder.build(uiKitInfo: uiKitInfo);Navigator.push(context, MaterialPageRoute(builder: (_) => rtkUI));Advanced color configuration — use RtkColorSwatch for precise control over each shade:
final designTokens = RtkDesignTokens( colorToken: RtkColorToken( brandColorSwatch: RtkColorSwatch(500, { 300: const Color(0xFFFF9A6C), 400: const Color(0xFFFF8552), 500: const Color(0xFFFF6B35), 600: const Color(0xFFE55A24), 700: const Color(0xFFCC4A14), }), backgroundColorSwatch: RtkColorSwatch(1000, { 600: const Color(0xFF666666), 700: const Color(0xFF4C4C4C), 800: const Color(0xFF333333), 900: const Color(0xFF1A1A1A), 1000: const Color(0xFF080808), }), textOnBrand: Colors.white, textOnBackground: Colors.white, ), borderRadius: RtkBorderRadius.extrarounded, borderWidth: RtkBorderWidth.thin,);Call provideRtkDesignSystem() with a DesignTokens object before or during rendering. Wrap your meeting components in RtkUIProvider.
import { useEffect } from 'react';
function App() { useEffect(() => { provideRtkDesignSystem({ theme: 'darkest', colors: { brand: generateBrandColors('#FF6B35'), text: '#FFFFFF', }, borderRadius: 'rounded', borderWidth: 'thin', fontFamily: 'Helvetica', }); }, []);
return ( <RtkUIProvider> {/* Your meeting components */} </RtkUIProvider> );}The generateBrandColors() helper derives five brand shades from a single hex value. Use generateBackgroundColors() for the same behavior with background colors.
The iOS UI Kit uses DesignLibrary.shared as its central design token registry. Create a custom configurator that conforms to DesignLibraryConfiguratorProtocol and pass it to the design library before starting a meeting.
import RealtimeKitUI
class CustomConfigurator: DesignLibraryConfiguratorProtocol { let colorBrandBase: BrandColorToken.Shade = .init(hex: "#FF6B35")! let colorBackgroundBase: BackgroundColorToken.Shade = .init(hex: "#080808")!
let textColorBackgroundBase: TextColorToken.Background.Shade = .init(hex: "#FFFFFF")! let textColorBrandBase: TextColorToken.Brand.Shade = .init(hex: "#111111")!
let statusDangerColor: StatusColor.Shade = .init(hex: "#FF2D2D")! let statusSuccessColor: StatusColor.Shade = .init(hex: "#83D017")! let statusWarningColor: StatusColor.Shade = .init(hex: "#FFCD07")!
let cornerRadiusRoundFactor: CGFloat = 4.0 let cornerRadiusExtraRoundFactor: CGFloat = 8.0 let cornerRadiusCircularFactor: CGFloat = 8.0
let borderSizeThinFactor: CGFloat = 1.0 let borderSizeFatFactor: CGFloat = 2.0}
// Apply the custom configuratorDesignLibrary.shared.setConfigurator(configurator: CustomConfigurator())The SDK auto-generates shade variations from each base color. Brand shades run 300–700 and background shades run 600–1000, derived by lightening the base color.
UI Kit uses design tokens ↗ for its design system.
Design tokens are the design related values which are used to maintain a design system, which provides flexibility in customizing the overall design of a system with values such as: typography, spacing, colors etc.
These design tokens are stored and shared among components with the help of CSS variables ↗.
The token system covers colors, borders, typography, and spacing. The table below shows the default values across all mobile platforms.
| Token | Android | Flutter | iOS | React Native |
|---|---|---|---|---|
| Brand color | #2160FD | #2160FD | #0246FD | #2160FD |
| Background | #080808 | #080808 | #050505 | #080808 |
| Text on background | #FFFFFF | #FFFFFF | #FFFFFF | #FFFFFF |
| Text on brand | #111111 | — | #111111 | #FFFFFF |
| Danger | #FF2D2D | #FF2D2D | #FF2D2D | #FF2D2D |
| Success | #83D017 | #83D017 | #83D017 | #83D017 |
| Warning | #FFCD07 | #FFCD07 | #FFCD07 | #FFCD07 |
You can tweak the font family used in your UI Kit components easily with this token. You can edit this value in two ways with the provideRtkDesignSystem utility.
--rtk-font-family: Inter;Set either of these values in your design tokens.
- With fontFamily - Use a custom font family, you'll have to load the font manually.
- With googleFont - Use a google font, the font is loaded automatically.
const designTokens = { fontFamily: "Custom Font", // or googleFont: "A Google Font",};Font customization is not available through the RtkDesignTokens API. The UI Kit uses the system font by default.
The Flutter UI Kit bundles the Inter font and uses it by default. Custom font configuration is not available through the RtkDesignTokens API.
Pass a fontFamily string to provideRtkDesignSystem() to use a custom font. You must load the font in your app before calling this function.
provideRtkDesignSystem({ fontFamily: "Helvetica",});The iOS UI Kit uses the system font (UIFont.systemFont) by default. Font customization is not exposed through the DesignLibraryConfiguratorProtocol. To change fonts, create a custom AppThemeProtocol implementation and override the appearance properties for individual components.
class CustomTheme: AppThemeProtocol { // ... var clockViewAppearance: RtkTextAppearance { let model = RtkTextAppearanceModel() model.font = UIFont(name: "Helvetica", size: 12) ?? .systemFont(ofSize: 12) return model } // ...}CSS Variables are set in the format: R G B.
Here are all the color tokens, along with their default values.
--rtk-colors-brand-500: 33 96 253;--rtk-colors-background-1000: 8 8 8;/* ... rest of the shades */A set of commonly used background shades are available by default with the theme property.
Theme values are: light, dark, darkest.
Edit color tokens like this. Only the colors you specify will be set.
const designTokens = { theme: "darkest", colors: { brand: { 500: "#0D51FD" }, background: { 1000: "#080808" }, text: "#ffffff", "text-on-brand": "#ffffff", "video-bg": "#181818", },};Brand color shades run from 300 (lightest) to 700 (darkest), with 500 as the primary shade. Background shades run from 600 (lightest) to 1000 (deepest).
Set colorBrandBase and colorBackgroundBase in your DesignLibraryConfiguratorProtocol implementation. The SDK auto-generates shades 300–700 for brand and 600–1000 for background by lightening the base color in 12% increments.
iOS also exposes a video property on BackgroundColorToken that controls the color behind video tiles when no stream is active. It defaults to shade800.
class CustomConfigurator: DesignLibraryConfiguratorProtocol { let colorBrandBase: BrandColorToken.Shade = .init(hex: "#FF6B35")! let colorBackgroundBase: BackgroundColorToken.Shade = .init(hex: "#1A1A1A")!
let textColorBackgroundBase: TextColorToken.Background.Shade = .init(hex: "#FFFFFF")! let textColorBrandBase: TextColorToken.Brand.Shade = .init(hex: "#111111")!
let statusDangerColor: StatusColor.Shade = .init(hex: "#FF2D2D")! let statusSuccessColor: StatusColor.Shade = .init(hex: "#83D017")! let statusWarningColor: StatusColor.Shade = .init(hex: "#FFCD07")!
// Border properties (required by protocol) let cornerRadiusRoundFactor: CGFloat = 4.0 let cornerRadiusExtraRoundFactor: CGFloat = 8.0 let cornerRadiusCircularFactor: CGFloat = 8.0 let borderSizeThinFactor: CGFloat = 1.0 let borderSizeFatFactor: CGFloat = 2.0}Android provides a videoBackground field on RtkColorTokens to set the color shown behind video tiles when no video stream is active. The default value is #333333.
val customColors = RtkColorTokens( brand = BrandColor( /* ... */ ), background = BackgroundColor( /* ... */ ), text = TextColor( /* ... */ ), videoBackground = Color.parseColor("#1A1A1A"),)React Native provides three preset themes that set a coordinated background color palette.
| Theme | Description |
|---|---|
darkest | Very dark background (default) |
dark | Dark background |
light | Light background |
Pass the theme property to provideRtkDesignSystem(). You can combine a preset theme with custom color overrides.
provideRtkDesignSystem({ theme: "dark", colors: { brand: generateBrandColors("#0246FD"), },});The spacing scale is used for setting width, height, margins, paddings, positions etc. throughout the components.
- The default value for the spacing scale base is 4px.
- Rest of the values are calculated with this base, set to
--rtk-space-1. - Current spacing scale ranges from 0 to 96.
--rtk-space-1: 4px;/* ... rest of the spacing scale */Set the base of the spacing scale with spacingBase property.
const designTokens = { spacingBase: 4, // value in px};The spacingBase property sets the base unit for the spacing scale in pixels. All spacing values in the UI Kit derive from this base.
provideRtkDesignSystem({ spacingBase: 4, // default: 4px});Spacing configuration is not available through the design token API on this platform.
The iOS UI Kit uses a SpaceToken with a base unit of 4 points. The spacing scale runs from space0 (0) to space9 (36). Spacing configuration is not exposed through the public DesignLibraryConfiguratorProtocol. All spacing values are derived internally from the base unit.
All mobile platforms support the same border radius and border width options.
| Token | Values |
|---|---|
borderRadius | sharp, rounded, extra-rounded, circular |
borderWidth | none, thin, fat |
Pass borderRadius and borderWidth directly to the RtkDesignTokens constructor.
val designTokens = RtkDesignTokens( colors = customColors, borderRadius = RtkBorderRadiusToken.Circular, borderWidth = RtkBorderWidthToken.Thin,)Pass borderRadius and borderWidth to the RtkDesignTokens constructor.
final designTokens = RtkDesignTokens( colorToken: colorToken, borderRadius: RtkBorderRadius.rounded, borderWidth: RtkBorderWidth.thin,);Pass borderRadius and borderWidth to provideRtkDesignSystem().
provideRtkDesignSystem({ borderRadius: "extra-rounded", borderWidth: "fat",});Set cornerRadiusRoundFactor, cornerRadiusExtraRoundFactor, cornerRadiusCircularFactor, borderSizeThinFactor, and borderSizeFatFactor in your DesignLibraryConfiguratorProtocol implementation. These factors control the multiplier used for each border style.
class CustomConfigurator: DesignLibraryConfiguratorProtocol { // ... color properties ...
let cornerRadiusRoundFactor: CGFloat = 4.0 let cornerRadiusExtraRoundFactor: CGFloat = 8.0 let cornerRadiusCircularFactor: CGFloat = 8.0
let borderSizeThinFactor: CGFloat = 1.0 let borderSizeFatFactor: CGFloat = 2.0}
DesignLibrary.shared.setConfigurator(configurator: CustomConfigurator())iOS uses BorderRadiusToken.RadiusType with values .sharp, .rounded, .extrarounded, and .circular. Border width uses BorderWidthToken.Width with values .none, .thin, and .fat.