---
title: Installation
slug: web-view-sdk-installation
createdAt: 2026-11-03T10:14:13.680Z
---

Add the package for your platform, then do the app setup it needs. Every platform also needs a bot key and a market slug from the Kindly platform

## Requirements

::::Tabs
:::Tab{title="iOS"}
- iOS 15.4 or later
- Swift Package Manager. The SDK is a signed binary, `KindlyWebView.xcframework`, and there is no CocoaPods pod for native iOS apps
:::

:::Tab{title="Android"}
- Android 5.0 (API 21) or later, and `compileSdk` 35 or later
- Kotlin 1.9.20 or later when your app is written in Kotlin. The API uses coroutines: `Deferred` results and `Flow` streams
- An Android System WebView that can run the chat, see [Checking Support](docId\:rVK8U_4vS0e5eH7w2XIWL)
:::

:::Tab{title="Flutter"}
- Flutter 3.27 or later and Dart 3.6 or later
- iOS 15.4 or later, with CocoaPods or Swift Package Manager
- Android `minSdk` 24 or later and `compileSdk` 36 or later
:::

:::Tab{title="React Native"}
- React Native 0.82 or later with the New Architecture. The package is a TurboModule
- iOS 15.4 or later, with CocoaPods
- Android `minSdk` 24 or later and `compileSdk` 35 or later
:::
::::

## Add the package

::::Tabs
:::Tab{title="iOS"}
In Xcode, choose File > Add Package Dependencies, enter `https://github.com/kindly-ai/sdk-chat-webview` and add the `KindlyWebView` product to your app target. In a `Package.swift`:

```swift
dependencies: [
    .package(url: "https://github.com/kindly-ai/sdk-chat-webview.git", from: "1.0.0"),
],
targets: [
    .target(name: "YourApp", dependencies: [
        .product(name: "KindlyWebView", package: "sdk-chat-webview"),
    ]),
]
```

A beta needs an exact pin, for example `exact: "X.Y.Z-beta.N"`, because `from:` never resolves a prerelease
:::

:::Tab{title="Android"}
The SDK is on Maven Central as `ai.kindly:sdk-webview`:

```kotlin
repositories {
    google()
    mavenCentral()
}

dependencies {
    implementation("ai.kindly:sdk-webview:1.0.0")
}
```

A beta has a version like `X.Y.Z-beta.N`. Pin an exact version rather than a dynamic one, which Gradle can resolve to a beta

The SDK brings `kotlinx-coroutines-core`, which is part of its API, and depends on AndroidX WebKit, OkHttp and Sentry's JVM core `io.sentry:sentry` 8. If your app also uses Sentry 8, Gradle resolves one version for both, the newer of the two
:::

:::Tab{title="Flutter"}
```yaml
dependencies:
  kindly_webview: ^1.0.0
```

Then run `flutter pub get`. A beta, for example `X.Y.Z-beta.N`, is a prerelease on pub.dev and pub prefers stable versions, so name the beta exactly to try it
:::

:::Tab{title="React Native"}
```shell
yarn add @kindly-ai/react-native-webview@1.0.0
cd ios && pod install
```

With npm, run `npm install @kindly-ai/react-native-webview@1.0.0` instead of `yarn add`. Autolinking does the rest. A beta, for example `X.Y.Z-beta.N`, is published under the npm dist-tag `beta`, so a plain install never picks it: install `@kindly-ai/react-native-webview@beta` or the exact version to try one
:::
::::

## Set up the app

::::Tabs
:::Tab{title="iOS"}
Add the [usage descriptions](docId\:sonmjcrRZMUEA1QI1eg5q) to your app's `Info.plist`. No `LSApplicationQueriesSchemes` entries are needed
:::

:::Tab{title="Android"}
Nothing to add, see [Android manifest and R8](docId\:sonmjcrRZMUEA1QI1eg5q)
:::

:::Tab{title="Flutter"}
Set the iOS deployment target of the Runner target to 15.4 or later. With CocoaPods, also set `platform :ios, '15.4'` in `ios/Podfile`. Then add the [usage descriptions](docId\:sonmjcrRZMUEA1QI1eg5q) to `ios/Runner/Info.plist`

An app built with the Xcode 27 SDK must adopt the UIScene lifecycle, or iOS 27 stops it at launch. That is Apple's rule for every app: declare a scene configuration with `FlutterSceneDelegate` as its delegate class in `Info.plist`, as Flutter's UIScene migration guide shows. The plugin works under scenes

On Android the plugin adds the Maven repository bundled in the package and resolves `ai.kindly:sdk-webview` only from there. Do not declare another version of that artifact in your app. A `settings.gradle` that sets `repositoriesMode` to `PREFER_SETTINGS` or `FAIL_ON_PROJECT_REPOS` ignores or refuses the repository the plugin adds, so keep the default mode
:::

:::Tab{title="React Native"}
Set `platform :ios, '15.4'` or later in `ios/Podfile` before `pod install`. Then add the [usage descriptions](docId\:sonmjcrRZMUEA1QI1eg5q) to your app's `Info.plist`

An app built with the Xcode 27 SDK must adopt the UIScene lifecycle, or iOS 27 stops it at launch. That is Apple's rule for every app: declare a scene configuration in `Info.plist` and create your window in a scene delegate instead of the app delegate. The SDK works under scenes

On Android the package registers its bundled copy of `ai.kindly:sdk-webview` as the only source for that artifact, so do not declare another version of it in your app. If your `settings.gradle` sets `repositoriesMode` to `PREFER_SETTINGS`, Gradle ignores that registration: add `node_modules/@kindly-ai/react-native-webview/android/maven-repo` to the settings repositories instead
:::
::::

## Usage descriptions on iOS

The chat lets people attach photos and videos and save images. iOS ends an app that reaches one of these features without its usage description, so add all four keys:

| Key                                 | Used for                          |
| ----------------------------------- | --------------------------------- |
| `NSCameraUsageDescription`          | Taking a photo or video to attach |
| `NSMicrophoneUsageDescription`      | Recording a video with sound      |
| `NSPhotoLibraryUsageDescription`    | Attaching from the photo library  |
| `NSPhotoLibraryAddUsageDescription` | Saving an image from the chat     |

The SDK logs an error at `start` when the camera, microphone or photo library add description is missing

## App-bound domains on iOS

If your app declares `WKAppBoundDomains`, list `chat.kindlycdn.com` in it. Without it WebKit blocks the chat's bridge, so the SDK reports itself unsupported and shows an unsupported screen instead of the chat

## Android manifest and R8

An Android app adds nothing, whether it uses the SDK directly or through Flutter or React Native. The SDK's manifest merges into your app with:

- the `INTERNET` permission
- its chat activity, not exported
- a `FileProvider` with the authority `${applicationId}.kindly.webview.fileprovider`, for photos taken in the chat
- a `<queries>` entry for `android.media.action.IMAGE_CAPTURE`, so the file picker can offer the camera

The consumer R8 rules ship inside the package and keep the SDK's classes, so a minified release build needs no rules of yours. The Android library is already minified

Next, [Initialization](docId\:MqmlgrN2Nv8ye8otUkYqC)
