> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Adding React Native support

The way Dynamic integrates with React Native is by extending our [client](/react-native/reference/client)
with the React Native Extension. This adds the `reactNative` module, which provides access to a *webview* component
that must be rendered to your app.

<Note>
  Since our client was built with a modular approach, each extension must be installed as a separate
  package, so to keep the client's package size to a minimum.
</Note>

## Installation

<Note>
  From **v4.83.0** onwards, the React Native SDK requires **Expo SDK 52 or later**. `@dynamic-labs/react-native-extension` declares `expo-modules-core: >=2.0.0` as a peer dependency, which is first satisfied by Expo SDK 52. Stay on **v4.82.x** if you need to support Expo SDK 50 or 51.
</Note>

Simply run the following in your terminal:

<Tabs>
  <Tab title="expo">
    ```bash Shell theme={"system"}
    npx expo install @dynamic-labs/react-native-extension react-native-webview expo-web-browser expo-linking expo-secure-store
    ```
  </Tab>

  <Tab title="npm">
    ```bash Shell theme={"system"}
    npm install @dynamic-labs/react-native-extension react-native-webview expo-web-browser expo-linking expo-secure-store
    ```
  </Tab>

  <Tab title="yarn">
    ```bash Shell theme={"system"}
    yarn install @dynamic-labs/react-native-extension react-native-webview expo-web-browser expo-linking expo-secure-store
    ```
  </Tab>
</Tabs>

## Prebuild (Expo) / Native linking

Since our SDK relies on native modules (e.g. `react-native-webview`, `expo-secure-store`), you need to
rebuild the native layer of your app after installing.

<Warning>
  **Expo Go is not supported.** Dynamic depends on native modules that are linked when you **prebuild** your app (for example with `npx expo prebuild` or an EAS/cloud build). Expo Go runs a generic prebuilt client and does **not** prebuild your project, so those native dependencies never make it into the binary you launch. Use a **development build**, **EAS Build**, or a **bare React Native** workflow instead.
</Warning>

<Tabs>
  <Tab title="Expo (managed)">
    If you're using Expo with a managed workflow, run:

    ```bash Shell theme={"system"}
    npx expo prebuild
    ```

    Then rebuild your app with `npx expo run:ios` or `npx expo run:android`.
  </Tab>

  <Tab title="EAS Build">
    If you're using [EAS Build](https://docs.expo.dev/build/introduction/), the native modules will be linked automatically during the cloud build. Simply run:

    ```bash Shell theme={"system"}
    eas build --profile <your-profile> --platform all
    ```

    Then install the resulting development build on your device or simulator.
  </Tab>

  <Tab title="Bare React Native">
    If you're using a bare React Native project, install the native dependencies:

    ```bash Shell theme={"system"}
    cd ios && pod install && cd ..
    ```

    Then rebuild your app using Xcode or `npx react-native run-ios` / `npx react-native run-android`.
  </Tab>
</Tabs>

## Usage with React Native

First, extend your client with our extension:

```typescript theme={"system"}
import { ReactNativeExtension } from '@dynamic-labs/react-native-extension';

export const dynamicClient = createClient({
  environmentId: 'YOUR-ENVIRONMENT-ID',
}).extend(ReactNativeExtension());
```

Next, render the webview injected into the client by the extension:

```typescript theme={"system"}
import { dynamicClient } from '<path to client file>';

export function App() {
  return (
    <>
      <dynamicClient.reactNative.WebView />

      <SafeAreaView>
        { ... }
      </SafeAreaView>
    </>
  )
}
```

You can read more about our react native package [here](/react-native/reference/package-references/react-native-extension).

## Embedded WebView (native overlay)

<Note>
  Available from **v4.82.0**.
</Note>

By default, the SDK renders its webview as a regular React Native component (via
`react-native-webview`) that you mount in your app tree. If your app's navigation
aggressively unmounts and remounts screens — or you simply want the wallet session to be
fully decoupled from your view tree — you can opt in to **embedded WebView mode**.

Pass `embeddedWebView: true` to the extension:

```typescript theme={"system"}
import { createClient } from '@dynamic-labs/client'
import { ReactNativeExtension } from '@dynamic-labs/react-native-extension'

export const dynamicClient = createClient({
  environmentId: 'YOUR-ENVIRONMENT-ID',
}).extend(
  ReactNativeExtension({
    appOrigin: 'https://your-app.example',
    embeddedWebView: true,
  }),
)
```

In this mode the SDK hosts the webview-controller inside a dedicated native overlay window
(`WKWebView` on iOS, `android.webkit.WebView` on Android) owned outside the React Native
view tree. The overlay is created lazily on first use and retained for the process
lifetime.

<Warning>
  When `embeddedWebView` is `true`, **do not render** `dynamicClient.reactNative.WebView`
  in your app — it resolves to a no-op component on the embedded path.
</Warning>

```typescript theme={"system"}
import { dynamicClient } from '<path to client file>';

export function App() {
  return (
    <SafeAreaView>
      { ... }
    </SafeAreaView>
  )
}
```

<Note>
  On platforms other than iOS / Android (e.g. web), the `embeddedWebView` flag is ignored
  and the standard `react-native-webview` path is used.
</Note>

### Caveats

* **No automatic load recovery.** Any HTTP error, network failure, blocked navigation,
  SSL error, or process termination surfaces as `core.initialization.error` with
  `WebViewFailedToLoadError`. Treat the SDK as un-initialised in your error handler.
* **Singleton.** Re-invoking `ReactNativeExtension({ embeddedWebView: true })` (e.g. when
  you recreate the client with a different `environmentId`) re-binds the JS bridge to the
  same native overlay rather than creating a new one.
* **Debugging** still works via `webviewDebuggingEnabled: true` (Safari Web Inspector on
  iOS, `chrome://inspect` on Android).
