# CallKit optional setup

## Custom ringtone setup

Below you can see ringtone audio resource requirements:

**Supported formats**:

- `.caf` (Core Audio Format) — recommended
- `.aiff` (Audio Interchange File Format)
- `.m4a` (MPEG-4 Audio)
- `.wav` (Waveform Audio)

**Duration**: under 30 seconds

**Naming**: simple name without spaces or special characters (e.g., ringtone.caf, my_ringtone.aiff)

### How to add custom ringtone file

<Tabs groupId="current-platform" queryString>

<Tab value="rn" label="React Native" default>

#### Step 1: Add the Sound File to Your Xcode Project

Open your iOS project in Xcode:

```bash
cd ios
open YourAppName.xcworkspace
```

In Xcode:

1. Right-click your main app folder/group in the Project Navigator
2. Select "Add Files to [YourAppName]..."
3. Choose your sound file
4. Ensure:
   - ✅ "Copy items if needed" is checked
   - ✅ "Create groups" is selected (not "Create folder references")
   - ✅ Your app target is selected in "Add to targets"
5. Click "Add"
6. Verify:
   - The file appears in the Project Navigator
   - In the File Inspector (right panel), the file is included in your app target

#### Step 2: Update Your Configuration

In your React Native code where you configure `StreamVideoRN.setPushConfig()`, set the sound property to match your filename (without the extension):

```javascript
StreamVideoRN.setPushConfig({
  ios: {
    sound: "ringtone", // Match your file name (without extension)
    // ... rest options
  },
  // ... rest of your configuration
});
```

**Examples:**

- File: `ringtone.caf` → Use `sound: 'ringtone'`
- File: `my_custom_ringtone.aiff` → Use `sound: 'my_custom_ringtone'`
- File: `incoming_call.m4a` → Use `sound: 'incoming_call'`

#### Step 3: Rebuild and Test

Rebuild your iOS app:

```bash
npx react-native run-ios
# or
yarn ios
```

Test with an incoming call to verify the custom ringtone plays.

</Tab>

<Tab value="expo" label="Expo">

#### Step 1: Place Your Sound File in the Project

Place your ringtone file anywhere in your project directory (e.g., `assets/ringtone.caf`).

#### Step 2: Add the Plugin Config

In `app.json`, add the `iosRingtone` property to the `@stream-io/video-react-native-sdk` plugin config. The path is relative to the project root:

```json title="app.json"
{
  "plugins": [
    [
      "@stream-io/video-react-native-sdk",
      {
        "ringing": true,
        "iosRingtone": "./assets/ringtone.caf"
      }
    ]
  ]
}
```

The plugin copies the file into the Xcode project and adds it to the app target's resources automatically.

#### Step 3: Update Your Configuration

Set the sound property to match your filename (without the extension):

```javascript
StreamVideoRN.setPushConfig({
  ios: {
    sound: "ringtone", // Match your file name (without extension)
    // ... rest options
  },
  // ... rest of your configuration
});
```

#### Step 4: Rebuild

```bash
npx expo prebuild --clean
npx expo run:ios
```

Test with an incoming call to verify the custom ringtone plays.

</Tab>

</Tabs>

## CallKit Icon setup

### Image Requirements

**Format:**

- `.png` (recommended)

**Design requirements:**

- Template image: monochrome (white/transparent or black/transparent)
- iOS will tint it automatically
- Square aspect ratio recommended
- Recommended sizes: 40x40pt, 60x60pt, or 80x80pt (provide @1x, @2x, @3x)

**Naming:**

- Simple name without spaces or special characters (e.g., `callkit_icon`, `app_icon`)

### How to add custom icon

<Tabs groupId="current-platform" queryString>

<Tab value="rn" label="React Native" default>

#### Method 1: Using Images.xcassets (Recommended)

**Prepare your image:**

- Create a monochrome template image (white/transparent or black/transparent)
- Export at @1x, @2x, and @3x (e.g., 40x40, 80x80, 120x120 pixels)

**Add the image to your Xcode project:**

Open your iOS project in Xcode:

```bash
cd ios
open YourAppName.xcworkspace
```

In Xcode:

1. In the Project Navigator, locate `Images.xcassets` (usually under your app folder)
2. Right-click `Images.xcassets` → "New Image Set"
3. Name it (e.g., `callkit_icon`)
4. Drag your images into the slots:
   - **1x**: @1x image
   - **2x**: @2x image
   - **3x**: @3x image
5. In the Attributes Inspector, set "Render As" to "Template Image"

**Update your configuration:**

```javascript
StreamVideoRN.setPushConfig({
  ios: {
    imageName: "callkit_icon", // Match your image set name
    // ... rest options
  },
  // ... rest of your configuration
});
```

**Rebuild and test:**

```bash
npx react-native run-ios
# or
yarn ios
```

#### Method 2: Using Direct PNG Files

**Prepare your image:**

- Create a monochrome template PNG
- Name it simply (e.g., `callkit_icon.png`)

**Add the file to your Xcode project:**

Open your iOS project in Xcode:

```bash
cd ios
open YourAppName.xcworkspace
```

In Xcode:

1. Right-click your main app folder/group
2. Select "Add Files to [YourAppName]..."
3. Choose your PNG file
4. Ensure:
   - ✅ "Copy items if needed" is checked
   - ✅ "Create groups" is selected
   - ✅ Your app target is selected
5. Click "Add"

**Update your configuration:**

```javascript
StreamVideoRN.setPushConfig({
  ios: {
    imageName: "callkit_icon", // Match your file name (without .png extension)
  },
  // ... rest of your configuration
});
```

**Rebuild and test:**

```bash
npx react-native run-ios
# or
yarn ios
```

</Tab>

<Tab value="expo" label="Expo">

#### Step 1: Place Your Icon File in the Project

Place a monochrome template PNG file anywhere in your project (e.g., `assets/callkit_icon.png`).

#### Step 2: Add the Plugin Config

In `app.json`, add the `iosCallKitIcon` property:

```json title="app.json"
{
  "plugins": [
    [
      "@stream-io/video-react-native-sdk",
      {
        "ringing": true,
        "iosCallKitIcon": "./assets/callkit_icon.png"
      }
    ]
  ]
}
```

The plugin creates an image set in `Images.xcassets` automatically with the correct template rendering intent.

<Admonition type="important">

**Name transformation:** The plugin converts the filename to PascalCase for the image set name. For example:

- `callkit_icon.png` → image set name: `CallkitIcon`
- `my-app-icon.png` → image set name: `MyAppIcon`
- `phone_icon.png` → image set name: `PhoneIcon`

You must use the **transformed name** in your `setPushConfig` configuration.

</Admonition>

#### Step 3: Update Your Configuration

Use the **transformed image set name** (PascalCase, no extension):

```javascript
StreamVideoRN.setPushConfig({
  ios: {
    imageName: "CallkitIcon", // PascalCase of your filename
    // ... rest options
  },
  // ... rest of your configuration
});
```

#### Step 4: Rebuild

```bash
npx expo prebuild --clean
npx expo run:ios
```

</Tab>

</Tabs>


---

This page was last updated at 2026-08-10T16:01:06.920Z.

For the most recent version of this documentation, visit [https://getstream.io/video/docs/react-native/advanced/incoming-calls/callkit-optional-setup/](https://getstream.io/video/docs/react-native/advanced/incoming-calls/callkit-optional-setup/).