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

# React Native Quickstart

> [card] Recommended: JavaScript SDK for React Native
>
> While this SDK is still supported, we recommend using newer [JavaScript SDK](https://docs.dynamic.xyz/docs/javascript/reference/react-native-quickstart.md), which is optimized for React Native, but also comes with a host of other benefits.

Get started with Dynamic's React Native SDK to add embedded wallets, multi-chain support, and flexible authentication (email, social login, passkeys) to your mobile app in just a few lines.

> [!NOTE]
>
> Before you start: You'll need Node.js 18+ and a Dynamic environment ID from the [Dynamic Console](https://console.dynamic.xyz/dashboard/developer/api).

> [!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.

> [tab] Agent-friendly
>
> > [!TIP]
> >
> > Add the Dynamic docs MCP to your AI editor first — your agent can then query the docs directly.
>
> > [tab] Cursor
> >
> > [Click here to add the MCP to Cursor.](https://cursor.com/en/install-mcp?name=dynamic\&config=eyJ1cmwiOiJodHRwczovL3d3dy5keW5hbWljLnh5ei9kb2NzL21jcCJ9)
>
> > [tab] Claude Code
> >
> > ```bash theme={"system"}
> > claude mcp add --transport http dynamic https://www.dynamic.xyz/docs/mcp
> > ```
>
> > [tab] Codex
> >
> > ```bash theme={"system"}
> > codex mcp add dynamic --url https://www.dynamic.xyz/docs/mcp
> > ```
>
> > [tab] Other
> >
> > If your editor or agent supports remote HTTP MCP, add a server that points at `https://www.dynamic.xyz/docs/mcp`. The exact steps depend on the product; use its MCP documentation for URL-based or HTTP transport setup.
>
> Copy this prompt into your LLM (e.g. Claude, ChatGPT, Cursor) to implement Dynamic in your React Native app.
>
> ````markdown theme={"system"}
> # React Native SDK Quickstart
>
> ## Purpose and Usage
>
> This document provides structured quickstart information for the Dynamic React Native SDK. It is designed to be consumed by LLMs to generate accurate installation commands and code examples based on user requirements.
>
> > **Architecture note:** The React Native SDK uses a client-based architecture with extensions. It is NOT the provider-based architecture of the React SDK. Do NOT use `DynamicContextProvider`, `DynamicWidget`, or any other React SDK patterns here. They are different SDKs.
>
> **How to use this document:**
>
> **BEFORE WRITING ANY CODE**, ask the user which path they want:
>
> > "Would you like a **Quick start** (Expo managed workflow + EVM, zero configuration, recommended if you're just getting started) or a **Custom setup** (choose your workflow, chains, passkeys, and account abstraction)?"
>
> Do not proceed until the user has answered. Do not assume a path.
>
> ---
>
> ## Quick Start Path
>
> > Use this path when the user chooses Quick start. Execute every step in order. Do not skip steps. Do not ask configuration questions.
>
> **Stack:** Expo managed workflow + pnpm + EVM only + no passkeys + no ZeroDev
>
> ### Step 1: Prerequisites
>
> Tell the user:
> - Node.js 18+ is required
> - React Native 0.73.6 or later and React 18 or 19 are required (the extension declares `react-native: >=0.73.6` and `react: >=18.0.0 <20.0.0`)
> - Expo SDK 52 or later is required (the extension declares `expo-modules-core: >=2.0.0`). Stay on `@dynamic-labs/legacy-react-native-extension@4.82.x` for Expo SDK 50 or 51
> - A Dynamic environment ID is required. Get one at https://console.dynamic.xyz/dashboard/developer
> - **This SDK is NOT compatible with Expo Go.** You must use a development build or EAS Build. If the user is using Expo Go, stop and inform them before proceeding.
> - Test on a real device early, since some features (passkeys, global wallets) do not work in simulators
>
> Ask the user for their environment ID before proceeding.
>
> ### Step 2: Scaffold the project
>
> ```bash
> pnpm dlx create-expo-app my-app --template blank-typescript
> cd my-app
> ```
>
> ### Step 3: Install
>
> Install all required packages explicitly. Missing peer dependencies cause runtime errors, not build errors. Install all of them.
>
> ```bash
> pnpm add @dynamic-labs/legacy-client @dynamic-labs/legacy-react-native-extension @dynamic-labs/legacy-viem-extension @dynamic-labs/legacy-react-hooks viem react-native-webview expo-web-browser expo-linking react-native-keychain react-native-fs @react-native-documents/picker @react-native-anywhere/polyfill-base64
> ```
>
> The native modules (`react-native-webview`, `react-native-keychain`) and the Expo modules (`expo-web-browser`, `expo-linking`) are peer dependencies of the React Native extension, so install them explicitly. `viem` is a peer dependency of the Viem extension, so it is not installed for you either. The extension's own native dependencies (`react-native-fs`, `@react-native-documents/picker`) are also listed explicitly because Metro cannot resolve transitive dependencies under pnpm.
>
> > **pnpm build scripts:** pnpm v10 suppresses build scripts by default. Add the following to your `package.json` before installing to avoid native module issues:
> > ```json
> > "pnpm": { "onlyBuiltDependencies": ["@react-native-community/cli", "react-native", "esbuild"] }
> > ```
>
> ### Step 4: Prebuild (required for native modules)
>
> The SDK relies on native modules (`react-native-webview`, `react-native-keychain`). You must rebuild the native layer after installing.
>
> ```bash
> npx expo prebuild
> ```
>
> > **CocoaPods UTF-8 error (macOS):** If `pod install` fails with `Unicode Normalization not appropriate for ASCII-8BIT`, run the following and retry:
> > ```bash
> > export LANG=en_US.UTF-8
> > npx expo prebuild
> > ```
>
> Then run your app:
> ```bash
> LANG=en_US.UTF-8 npx expo run:ios
> # or
> LANG=en_US.UTF-8 npx expo run:android
> ```
>
> > **Warning:** Do not use `npx expo start` with Expo Go after this step. It will not work. Always use `expo run:ios` / `expo run:android` or a development build.
>
> ### Step 5: Initialize the client
>
> Create a `client.ts` file at the project root. Import the base64 polyfill first, in your app's entry point:
>
> ```typescript
> import '@react-native-anywhere/polyfill-base64';
> ```
>
> On Expo SDK 53 and below you also need `text-encoding`, `react-native-get-random-values`, and `buffer`. See https://docs.dynamic.xyz/react-native/reference/polyfills.
>
> ```typescript
> import { createClient } from '@dynamic-labs/legacy-client';
> import { ReactNativeExtension } from '@dynamic-labs/legacy-react-native-extension';
> import { ViemExtension } from '@dynamic-labs/legacy-viem-extension';
>
> export const dynamicClient = createClient({
>   environmentId: 'YOUR_ENVIRONMENT_ID',
>   appLogoUrl: 'https://demo.dynamic.xyz/favicon-32x32.png',
>   appName: 'My App',
> })
>   .extend(ReactNativeExtension({ appOrigin: 'http://localhost:8081' }))
>   .extend(ViemExtension());
> ```
>
> > **`appOrigin` belongs on `ReactNativeExtension`, not on `createClient`.** `createClient` does not accept it and TypeScript will reject it there. It sets the web origin used for SIWE messages, fetch `Origin` headers, and passkey operations, and it must match an origin allowlisted in the console. Use `http://localhost:8081` for local Expo development and your real domain in production.
>
> ### Step 6: Add the WebView to your app
>
> Open `App.tsx` (or `App.js` if your project uses JavaScript) and replace the contents:
>
> ```typescript
> // App.tsx
> import { SafeAreaView, Text } from 'react-native';
> import { dynamicClient } from './client';
>
> export default function App() {
>   return (
>     <>
>       <dynamicClient.reactNative.WebView />
>       <SafeAreaView>
>         <Text>Hello from Dynamic!</Text>
>       </SafeAreaView>
>     </>
>   );
> }
> ```
>
> ### Step 7: Read wallet state in a component
>
> Use `useReactiveClient` from `@dynamic-labs/legacy-react-hooks` to reactively access client state in React components:
>
> ```typescript
> import { useReactiveClient } from '@dynamic-labs/legacy-react-hooks';
> import { dynamicClient } from './client';
>
> export function WalletInfo() {
>   const { wallets } = useReactiveClient(dynamicClient);
>   const wallet = wallets.userWallets[0];
>
>   if (!wallet) return null;
>
>   return <Text>Address: {wallet.address}</Text>;
> }
> ```
>
> ### Step 8: Console configuration checklist
>
> Before testing, verify these settings in your Dynamic Console at https://console.dynamic.xyz:
>
> 1. **Chains enabled**: go to **Chains & Networks** and enable EVM
> 2. **Embedded wallets enabled**: go to **Wallets** and enable embedded wallets
> 3. **Login method enabled**: go to **Sign-in Methods** and enable at least one (e.g. email OTP)
> 4. **CORS origin allowlisted**: go to **Security → Allowed Origins** and add your app's origin (e.g. `http://localhost:8081`)
> 5. **Deeplink URL registered**: go to **Security → Deeplink URLs** and add your app's deeplink scheme (required for social login and OAuth flows). See https://docs.dynamic.xyz/react-native/reference/deeplink-urls for setup instructions.
>
> ---
>
> ## Custom Setup Path
>
> > Use this path when the user chooses Custom setup. Ask ALL questions below before generating any code.
>
> **Questions to ask the user:**
>
> 1. Which workflow are you using? (Expo managed, EAS Build, bare React Native)
> 2. Which package manager do you prefer? (npm, yarn, pnpm, bun, expo)
> 3. Which chains do you want to support? (EVM, SVM, Sui, one or more)
> 4. Do you want to enable passkeys?
> 5. If EVM: do you want to enable Account Abstraction (ZeroDev)?
>
> **Only after receiving answers**, use the sections below to generate the correct setup.
>
> ### Package Manager Commands
> - `npm`: `npm i`
> - `yarn`: `yarn add`
> - `pnpm`: `pnpm add`
> - `bun`: `bun add`
> - `expo`: `npx expo install`
>
> ### Package Mapping
>
> Always install all of the following explicitly. Missing peer dependencies cause runtime errors, not build errors.
>
> - Core (always required): `@dynamic-labs/legacy-client`
> - React Native extension (always required): `@dynamic-labs/legacy-react-native-extension`
> - EVM: `@dynamic-labs/legacy-viem-extension` + `viem` (peer dependency, range `^2.45.3`)
> - SVM: `@dynamic-labs/legacy-solana-extension` + `@solana/web3.js@1.98.1` (peer dependency, pinned by the extension)
> - Sui: `@dynamic-labs/legacy-sui-extension` + `@mysten/sui@2.8.0` (peer dependency, pinned by the extension)
> - ZeroDev (EVM only): `@dynamic-labs/legacy-zerodev-extension` + `events`
> - Native peer dependencies (always required): `react-native-webview`, `expo-web-browser`, `expo-linking`, `react-native-keychain`
> - Extension native dependencies (always required; explicit under pnpm because Metro cannot resolve transitive dependencies): `react-native-fs`, `@react-native-documents/picker`
> - Polyfills (always required): `@react-native-anywhere/polyfill-base64`, plus `text-encoding`, `react-native-get-random-values`, and `buffer` on Expo SDK 53 and below (https://docs.dynamic.xyz/react-native/reference/polyfills)
> - Passkeys: the extension already depends on `react-native-passkey`, so do not pin an older version yourself
>
> The chain extensions declare their chain SDK as a peer dependency and the SVM and Sui peers are pinned to an exact version, so install the version the installed extension declares. Check its `peerDependencies` if the install reports a peer conflict.
>
> ### Prebuild / Native Linking
>
> Always required after install. The SDK relies on native modules.
>
> - **Expo managed**: `npx expo prebuild` → `npx expo run:ios` or `npx expo run:android`
> - **EAS Build**: native modules linked automatically. Run `eas build --profile <your-profile> --platform all`
> - **Bare React Native**: `cd ios && pod install && cd ..` → rebuild with Xcode or `npx react-native run-ios` / `npx react-native run-android`
>
> > **Warning:** This SDK is NOT compatible with Expo Go. Always use a development build or EAS Build.
>
> ### Extension Mapping
> - EVM → `ViemExtension` from `@dynamic-labs/legacy-viem-extension`
> - SVM → `SolanaExtension` from `@dynamic-labs/legacy-solana-extension`
> - Sui → `SuiExtension` from `@dynamic-labs/legacy-sui-extension`
> - ZeroDev → `ZeroDevExtension` from `@dynamic-labs/legacy-zerodev-extension`
>
> ### Client Initialization
>
> ```typescript
> import { createClient } from '@dynamic-labs/legacy-client';
> import { ReactNativeExtension } from '@dynamic-labs/legacy-react-native-extension';
>
> export const dynamicClient = createClient({
>   environmentId: 'YOUR_ENVIRONMENT_ID',
>   appLogoUrl: 'https://demo.dynamic.xyz/favicon-32x32.png',
>   appName: 'My App',
> })
>   .extend(ReactNativeExtension({ appOrigin: 'https://YOUR-DOMAIN.com' }))
>   .extend({CHAIN_EXTENSIONS});
> ```
>
> `appOrigin` is an option of `ReactNativeExtension`, never of `createClient`. It is optional in the type but required in practice for SIWE messages and passkeys, and it must match an origin allowlisted in the console.
>
> ### WebView (required)
>
> Always include `<dynamicClient.reactNative.WebView />` at the root of your component tree. Without it, the SDK's UI and auth flows will not function.
>
> ### Reactive State in Components
>
> Use `useReactiveClient` from `@dynamic-labs/legacy-react-hooks` to access client state reactively in React components. Do NOT use React SDK hooks (`useDynamicContext`, etc.). They do not exist in this SDK.
>
> ```typescript
> import { useReactiveClient } from '@dynamic-labs/legacy-react-hooks';
> import { dynamicClient } from './client';
>
> const { wallets } = useReactiveClient(dynamicClient);
> ```
>
> ### TODOs for custom config
>
> **When passkeys are enabled:**
> ```typescript
> // TODO: Complete passkey setup - https://docs.dynamic.xyz/react-native/reference/setup-passkey
> ```
>
> **When ZeroDev is enabled:**
> ```typescript
> // TODO: Check for file resolution error fix - https://docs.dynamic.xyz/react-native/reference/wallets/account-abstraction#resolve-file-resolution-error-optional
> ```
>
> **When social login is needed:**
> ```typescript
> // TODO: Configure deeplink URLs - https://docs.dynamic.xyz/react-native/reference/deeplink-urls
> ```
>
> ### Valid Chain Combinations
> - Any single chain or combination of EVM, SVM, and Sui is valid
> - ZeroDev only applies when EVM is selected
> - At least one chain must be selected
>
> ### Documentation
> All docs for this SDK: https://docs.dynamic.xyz (paths starting with `/react-native/`)
> Environment ID: https://console.dynamic.xyz/dashboard/developer/api
>
> ---
>
> ## Critical Reference
>
> | Correct | Incorrect | Notes |
> |---|---|---|
> | `createClient().extend(ReactNativeExtension())` | `DynamicContextProvider` / `DynamicWidget` | React Native uses client + extensions, not providers |
> | `useReactiveClient(dynamicClient)` | `useDynamicContext()` | React SDK hooks do not exist in this SDK |
> | `<dynamicClient.reactNative.WebView />` | Omitting WebView | Required in component tree. Auth flows will silently fail without it |
> | `ReactNativeExtension({ appOrigin: 'https://your-domain.com' })` | `createClient({ appOrigin: ... })` | `appOrigin` is an extension option; `createClient` rejects it |
> | `npx expo run:ios` / `npx expo run:android` | `npx expo start` with Expo Go | Expo Go does not support custom native modules |
> | Install all packages explicitly | Rely on transitive deps | Missing peer deps cause runtime errors, not build errors |
>
> ---
>
> ## Building a headless integration?
>
> If you're building without the Dynamic Widget, see the [Authentication screens](/react-native/authentication-methods/headless-authentication) for a full list of screens your app needs to handle.
>
> ---
>
> ## Step-Up Authentication
>
> **Required before accepting the `2026_04_01` API version**. Verify your
> minimum API version in [Console > Developers > API & SDK Keys](https://console.dynamic.xyz/dashboard/developer/api).
>
> The SDK provides built-in step-up UI via
> `dynamicClient.stepUpAuth.promptStepUpAuth`. **If building a headless/custom
> UI, you must handle step-up authentication manually**: check requirements
> with `isStepUpRequired` and call the appropriate prompt or individual verify
> method yourself.
>
> See [Step-up authentication](/react-native/authentication-methods/step-up-auth/overview) for the full implementation guide.
>
> ---
>
> ## Device Registration
>
> **Required before accepting the `2026_04_01` API version**. Verify your
> minimum API version in [Console > Developers > API & SDK Keys](https://console.dynamic.xyz/dashboard/developer/api).
>
> If using Dynamic's built-in UI (default), device registration is handled
> automatically. No code required. **If building a headless/custom UI**
> (`deviceRegistrationModal: { enabled: false }`), **you must manually check
> whether the current device needs registration and handle the completion
> event yourself.**
>
> Full guide: https://docs.dynamic.xyz/react-native/authentication-methods/device-registration
>
> ---
>
> ## Troubleshooting
>
> ### 1: App crashes immediately after install
> Native modules were not linked. Run `npx expo prebuild` and rebuild with `npx expo run:ios` or `npx expo run:android`. Do not use Expo Go.
>
> ### 2: Auth flow does nothing / WebView not showing
> `<dynamicClient.reactNative.WebView />` is missing from the component tree. Add it at the root level of your app.
>
> ### 3: Wallet creation fails or returns no wallet
> Check the console: embedded wallets must be enabled under **Wallets**, chains must be enabled under **Chains & Networks**, and the app origin must be allowlisted under **Security → Allowed Origins**.
>
> ### 4: Social login / OAuth redirects fail
> Deeplink URLs must be registered in the Dynamic Console under **Security → Deeplink URLs**. Your app URL scheme must also be configured in `app.json`. See https://docs.dynamic.xyz/react-native/reference/deeplink-urls.
>
> ### 5: Passkey errors
> Passkeys require additional native setup beyond installing the package and setting `appOrigin`. Follow the full passkey setup guide: https://docs.dynamic.xyz/react-native/reference/setup-passkey. Passkeys also do not work in simulators, so test on a real device.
>
> ### 6: Wrong hook or import errors
> Do not use React SDK imports (`@dynamic-labs/sdk-react-core`, `useDynamicContext`, etc.) in a React Native project. The React Native SDK is a separate package with a different API surface. Some docs pages under the React Native section may show React SDK patterns for certain chains. Those examples are not correct for the React Native client-based architecture.
>
> If the issue persists, check https://docs.dynamic.xyz/react-native/reference/troubleshooting and https://docs.dynamic.xyz/overview/troubleshooting/general.
> ````

> [tab] Manual
>
> [https://documentation-quickstarts.vercel.app/react-native?color-scheme=dark](https://documentation-quickstarts.vercel.app/react-native?color-scheme=dark)
>
> [https://documentation-quickstarts.vercel.app/react-native?color-scheme=light](https://documentation-quickstarts.vercel.app/react-native?color-scheme=light)
>
> ## Prebuild (Expo) / Native linking
>
> Since our SDK relies on native modules (e.g. `react-native-webview`, `react-native-keychain`), you need to
> rebuild the native layer of your app after installing.
>
> > [tab] 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] 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] 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`.
>
> > [!NOTE]
> >
> > Use the **client** and its modules; use `useReactiveClient` from `@dynamic-labs/legacy-react-hooks` when you need reactive state in components.
>
> > [!WARNING]
> >
> > Set `appOrigin` on the `ReactNativeExtension`, not on `createClient`: `ReactNativeExtension({ appOrigin: 'https://your-domain.com' })`. It is used for SIWE messages, fetch `Origin` headers, and passkey operations.
>
> ## Polyfills
>
> Please refer to the [Polyfills](https://docs.dynamic.xyz/docs/react-native/reference/polyfills.md) section for information on how to set up necessary polyfills.
>
> ## Setup Deeplink URLs
>
> In order to use most of the React Native features (such as social connections), you will first
> have to set up the list of mobile deeplink URLs Dynamic may use to redirect back to your app.
>
> For detailed instructions on configuring deeplinks, please refer to our [Deeplink URLs](https://docs.dynamic.xyz/docs/react-native/reference/deeplink-urls.md) guide.
>
> ## Next Steps
>
> > [!WARNING]
> >
> > **Step-up authentication** and **device registration** are required
> > before accepting the `2026_04_01` API version. If you have a headless
> > integration, you must implement both manually.
> > See the [upgrade guide](https://docs.dynamic.xyz/docs/get-started/migrations/api/2026_04_01.md).
>
> * [Step-up authentication](https://docs.dynamic.xyz/docs/react-native/authentication-methods/step-up-auth/overview.md)
>
> * [Device registration](https://docs.dynamic.xyz/docs/react-native/authentication-methods/device-registration.md)
>
> > [!NOTE]
> >
> > Building without the Dynamic Widget? See the [Authentication screens](https://docs.dynamic.xyz/docs/react-native/authentication-methods/headless-authentication.md) for a full list of screens your app needs to handle.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.