Skip to main content

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.

The way Dynamic integrates with React Native is by extending our 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.
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.

Installation

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.
Simply run the following in your terminal:
Shell
npx expo install @dynamic-labs/react-native-extension react-native-webview expo-web-browser expo-linking expo-secure-store

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.
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.
If you’re using Expo with a managed workflow, run:
Shell
npx expo prebuild
Then rebuild your app with npx expo run:ios or npx expo run:android.

Usage with React Native

First, extend your client with our extension:
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:
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.

Embedded WebView (native overlay)

Available from v4.82.0.
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:
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.
When embeddedWebView is true, do not render dynamicClient.reactNative.WebView in your app — it resolves to a no-op component on the embedded path.
import { dynamicClient } from '<path to client file>';

export function App() {
  return (
    <SafeAreaView>
      { ... }
    </SafeAreaView>
  )
}
On platforms other than iOS / Android (e.g. web), the embeddedWebView flag is ignored and the standard react-native-webview path is used.

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).