> ## Documentation Index
> Fetch the complete documentation index at: https://cometchat-22654f5b-docs-audit-content-webhooks.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Customizing Your UI Kit Builder

> Customize CometChat UI Kit Builder components — modify props, styling, and behavior for React Native.

The `config.json` file handles basic feature toggles. For deeper customizations, modify the Zustand store, theme configuration, or component props directly.

***

## Understanding the Customization Architecture

The React Native UI Kit Builder uses these main files for customization:

| File          | Purpose                                   | When to Modify                               |
| ------------- | ----------------------------------------- | -------------------------------------------- |
| `config.json` | Feature flags and configuration constants | Functional changes (enable/disable features) |
| `store.ts`    | Zustand store for state management        | Runtime configuration updates                |
| Theme object  | Colors, typography, and styling           | UI/visual changes                            |

<Info>
  The `config.json` file is the source of truth for your Builder configuration. You can update it manually or by scanning a QR code with new settings.
</Info>

***

## Using the Configuration Store

The Zustand store manages your Builder configuration at runtime. Access it anywhere in your app to read or update settings.

### Reading Configuration

```tsx theme={null}
import { useConfig } from './src/config/store';

const MyComponent = () => {
  // Access entire settings object
  const settings = useConfig((state) => state.settings);
  
  // Access specific feature category
  const chatFeatures = useConfig((state) => state.settings.chatFeatures);
  
  // Access style configuration
  const styleConfig = useConfig((state) => state.settings.style);
  
  return (/* ... */);
};
```

### Updating Configuration at Runtime

```tsx theme={null}
import { useConfigStore } from './src/config/store';

// Update a specific setting
const updateFeature = () => {
  const store = useConfigStore.getState();
  store.updateSettings({
    ...store.settings,
    chatFeatures: {
      ...store.settings.chatFeatures,
      coreMessagingExperience: {
        ...store.settings.chatFeatures.coreMessagingExperience,
        photosSharing: false,
      },
    },
  });
};
```

<Note>
  Runtime changes to the store are not persisted by default. Use AsyncStorage to save and restore configurations.
</Note>

***

## Theme Customization

### Applying Builder Theme to UI Kit

The Builder configuration includes style settings that should be applied to the CometChat UI Kit theme. The `getFontFamily` helper used below is defined in [Custom Font Integration](#custom-font-integration); import it from wherever you place that utility.

```tsx theme={null}
import React from 'react';
import { CometChatThemeProvider } from '@cometchat/chat-uikit-react-native';
import { useConfig } from './src/config/store';
import { getFontFamily } from './src/utils/fonts'; // defined in "Custom Font Integration" below

const App = () => {
  const styleConfig = useConfig((state) => state.settings.style);
  const fontFamily = getFontFamily(styleConfig.typography.font);

  const theme = {
    light: {
      color: {
        primary: styleConfig.color.brandColor,
        textPrimary: styleConfig.color.primaryTextLight,
        textSecondary: styleConfig.color.secondaryTextLight,
        background: '#FFFFFF',
        border: '#E8E8E8',
      },
    },
    dark: {
      color: {
        primary: styleConfig.color.brandColor,
        textPrimary: styleConfig.color.primaryTextDark,
        textSecondary: styleConfig.color.secondaryTextDark,
        background: '#141414',
        border: '#3D3D3D',
      },
    },
  };

  return (
    <CometChatThemeProvider theme={theme}>
      {/* Your app components */}
    </CometChatThemeProvider>
  );
};
```

<Note>
  The UI Kit's `typography` theme tokens are keyed by named text styles (for example `heading4`) and each has `bold`, `medium`, and `regular` variants whose `fontFamily` is a string—not a single top-level `fontFamily`. To apply a Builder-selected font across the UI, set the `fontFamily` on the relevant typography tokens. See [Component Styling](/ui-kit/react-native/component-styling) for the exact token structure and [Theming](/ui-kit/react-native/theme) for the theme provider overview.
</Note>

### Custom Color Palette

Override the default colors by modifying the theme object:

```tsx theme={null}
const customTheme = {
  light: {
    color: {
      primary: '#FF6B6B',        // Custom brand color
      textPrimary: '#2D3436',    // Custom primary text
      textSecondary: '#636E72',  // Custom secondary text
      success: '#00B894',        // Success state
      error: '#D63031',          // Error state
      warning: '#FDCB6E',        // Warning state
    },
  },
  dark: {
    color: {
      primary: '#FF6B6B',
      textPrimary: '#DFE6E9',
      textSecondary: '#B2BEC3',
      success: '#00B894',
      error: '#FF7675',
      warning: '#FFEAA7',
    },
  },
};
```

***

## Custom Font Integration

### Step 1: Add Font Files

Add your custom font files to the project's `assets/fonts/` directory (and reference them from the platform font folders described in the [Directory Structure](/chat-builder/react-native/builder-dir-structure) guide):

* **iOS:** `ios/<App>/Resources/Fonts/`
* **Android:** `android/app/src/main/assets/fonts/`

### Step 2: Register Fonts

<Tabs>
  <Tab title="React Native CLI (bare)">
    Native modules in React Native 0.60+ are linked automatically by autolinking, so the legacy `react-native link` command is no longer used. To copy your font assets into the native projects, declare them in `react-native.config.js`:

    ```js theme={null}
    module.exports = {
      assets: ['./assets/fonts'],
    };
    ```

    Then run:

    ```bash theme={null}
    npx react-native-asset
    ```

    Rebuild the app (`npm run ios` / `npm run android`) so the fonts are bundled.
  </Tab>

  <Tab title="Expo (development build)">
    In an Expo development build, register fonts with the `expo-font` config plugin in `app.json` instead of `react-native-asset`, then rebuild the development client. Refer to the [Expo Integration](/ui-kit/react-native/expo-integration) guide for the native setup CometChat requires under Expo.
  </Tab>
</Tabs>

### Step 3: Map Font Family

Create a font mapping utility. `getFontFamily` returns the base font-family **string** for a given Builder font name, so it can be assigned to the UI Kit's `fontFamily` typography tokens:

```tsx theme={null}
import { Platform } from 'react-native';

const FONT_MAP: Record<string, string> = {
  'roboto': Platform.OS === 'ios' ? 'Roboto-Regular' : 'roboto_regular',
  'inter': Platform.OS === 'ios' ? 'Inter-Regular' : 'inter_regular',
  'your-custom-font': Platform.OS === 'ios' ? 'YourFont-Regular' : 'your_font_regular',
};

export const getFontFamily = (fontName: string): string => {
  return FONT_MAP[fontName] || FONT_MAP['roboto'];
};
```

<Note>
  The exact font-family name must match the PostScript name of the installed font (iOS) or the file name without extension (Android). Verify the registered names after running the registration step above.
</Note>

***

## Component-Level Customizations

### Conditional Rendering Based on Features

Use the configuration store to conditionally render UI elements:

```tsx theme={null}
import { useConfig } from './src/config/store';

const MessageComposer = () => {
  const chatFeatures = useConfig((state) => state.settings.chatFeatures);
  const { coreMessagingExperience, deeperUserEngagement } = chatFeatures;

  return (
    <View>
      {/* Always show text input */}
      <TextInput placeholder="Type a message..." />
      
      {/* Conditionally show attachment options */}
      {coreMessagingExperience.photosSharing && (
        <PhotoAttachmentButton />
      )}
      
      {coreMessagingExperience.fileSharing && (
        <FileAttachmentButton />
      )}
      
      {deeperUserEngagement.voiceNotes && (
        <VoiceNoteButton />
      )}
      
      {deeperUserEngagement.stickers && (
        <StickerButton />
      )}
    </View>
  );
};
```

### Customizing Message Options

Control which message options appear based on configuration:

```tsx theme={null}
const MessageOptions = ({ message }) => {
  const chatFeatures = useConfig((state) => state.settings.chatFeatures);
  const { coreMessagingExperience, deeperUserEngagement, moderatorControls } = chatFeatures;

  const options = [];

  if (coreMessagingExperience.quotedReplies) {
    options.push({ label: 'Reply', action: 'reply' });
  }

  if (coreMessagingExperience.threadConversationAndReplies) {
    options.push({ label: 'Reply in Thread', action: 'thread' });
  }

  if (deeperUserEngagement.reactions) {
    options.push({ label: 'React', action: 'react' });
  }

  if (coreMessagingExperience.editMessage && message.sender.uid === currentUser.uid) {
    options.push({ label: 'Edit', action: 'edit' });
  }

  if (coreMessagingExperience.deleteMessage && message.sender.uid === currentUser.uid) {
    options.push({ label: 'Delete', action: 'delete' });
  }

  if (moderatorControls.reportMessage) {
    options.push({ label: 'Report', action: 'report' });
  }

  return <OptionsMenu options={options} />;
};
```

***

## Persisting Configuration

### Save Configuration to AsyncStorage

```tsx theme={null}
import AsyncStorage from '@react-native-async-storage/async-storage';
import { useConfigStore } from './src/config/store';

const CONFIG_KEY = '@cometchat_builder_config';

export const saveConfig = async () => {
  try {
    const config = useConfigStore.getState();
    await AsyncStorage.setItem(CONFIG_KEY, JSON.stringify(config));
  } catch (error) {
    console.error('Failed to save config:', error);
  }
};

export const loadConfig = async () => {
  try {
    const savedConfig = await AsyncStorage.getItem(CONFIG_KEY);
    if (savedConfig) {
      const parsed = JSON.parse(savedConfig);
      useConfigStore.getState().updateConfig(parsed);
    }
  } catch (error) {
    console.error('Failed to load config:', error);
  }
};
```

### Auto-save on Configuration Changes

```tsx theme={null}
import { useEffect } from 'react';
import { useConfigStore } from './src/config/store';

const ConfigPersistence = () => {
  const config = useConfigStore((state) => state);

  useEffect(() => {
    // Debounce saves to avoid excessive writes
    const timeoutId = setTimeout(() => {
      saveConfig();
    }, 1000);

    return () => clearTimeout(timeoutId);
  }, [config]);

  return null;
};
```

***

## Layout Customization

### Dynamic Tab Configuration

```tsx theme={null}
import { useConfig } from './src/config/store';

const TabNavigator = () => {
  const layout = useConfig((state) => state.settings.layout);
  const { tabs, withSideBar } = layout;

  if (!withSideBar) {
    return <SingleChatView />;
  }

  return (
    <Tab.Navigator>
      {tabs.includes('chats') && (
        <Tab.Screen name="Chats" component={ChatsScreen} />
      )}
      {tabs.includes('calls') && (
        <Tab.Screen name="Calls" component={CallsScreen} />
      )}
      {tabs.includes('users') && (
        <Tab.Screen name="Users" component={UsersScreen} />
      )}
      {tabs.includes('groups') && (
        <Tab.Screen name="Groups" component={GroupsScreen} />
      )}
    </Tab.Navigator>
  );
};
```

***

## Going Beyond the Builder

The Builder config covers feature toggles, layout, and high-level theme tokens. For deeper customization, drop down to the UI Kit's own customization layers—these work the same whether or not you use the Builder:

<CardGroup cols={2}>
  <Card title="Message Templates" href="/ui-kit/react-native/message-list">
    Override how message bubbles render with `CometChatMessageTemplate` and the `templates` prop on the message list.
  </Card>

  <Card title="Component Styling & View Slots" href="/ui-kit/react-native/component-styling">
    Style individual components and inject custom views (headers, subtitles, list items) via theme overrides and slot props.
  </Card>

  <Card title="Theme Overrides" href="/ui-kit/react-native/theme">
    Customize colors, typography tokens, and light/dark modes through `CometChatThemeProvider`.
  </Card>

  <Card title="Builder Settings Reference" href="/chat-builder/react-native/builder-settings">
    Full schema for every `config.json` key the Builder exports.
  </Card>
</CardGroup>
