# Getting Started with React Native

<SkillCard title="AI Skill" subtitle="@openfort/react-native" source="npm" subtitleHref="https://www.npmjs.com/package/@openfort/react-native" description="Pre-built prompt with the full setup reference." content={skillContent} fileName="SKILL.md" />

::::steps

## Create your app (optional)

If you're starting from scratch, create a new React Native app with Expo. If you already have an app, skip this step.

### Create a new Expo app

You can use Expo's `create-expo-app` to create a blank template Typescript app.

:::code-group

```sh [With expo-router]
npx --yes create-expo-app@latest my-app --template tabs
cd my-app
```

```sh [Without expo-router]
npx --yes create-expo-app@latest my-app --template expo-template-blank-typescript
cd my-app
```

:::

### Run the app

From your project directory, run one of:

```bash
npm run android
npm run ios
```

## Install dependencies

Install the latest version of the [Openfort React Native SDK](https://www.npmjs.com/package/@openfort/react-native) and its required dependencies:

:::code-group

```sh [With expo-router]
npx --yes expo install expo-router expo-apple-authentication expo-application expo-crypto expo-secure-store expo-constants
npm install react-native-get-random-values @openfort/react-native
```

```sh [Without expo-router]
npx --yes expo install expo-apple-authentication expo-application expo-crypto expo-secure-store expo-constants
npm install react-native-get-random-values @openfort/react-native
```

:::

## Configure Metro

Create or update your `metro.config.js` to include the necessary Node.js module shims:

```tsx
// metro.config.js
const { getDefaultConfig } = require("expo/metro-config");

/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(__dirname);

const resolveRequestWithPackageExports = (context, moduleName, platform) => {
  // Package exports in `jose` are incorrect, so we need to force the browser version
  if (moduleName === "jose") {
    const ctx = {
      ...context,
      unstable_conditionNames: ["browser"],
    };
    return ctx.resolveRequest(ctx, moduleName, platform);
  }

  return context.resolveRequest(context, moduleName, platform);
};

config.resolver.resolveRequest = resolveRequestWithPackageExports;

module.exports = config;
```

## Set up entry point

Create `entrypoint.ts`. Ensure `react-native-get-random-values` is imported first.
Without it, the library `crypto` does not load properly and causes an error.

:::code-group

```ts [With expo-router]
// entrypoint.ts
import "react-native-get-random-values";
import "expo-router/entry";
```

```ts [Without expo-router]
// entrypoint.ts
import "react-native-get-random-values";
import { registerRootComponent } from 'expo';
import App from './App';
registerRootComponent(App);
```

:::

Also, update your `package.json` to use the corresponding entry point:

```json
{
  ...
  "main": "entrypoint.ts",
  ...
}
```

## Wrap your app with OpenfortProvider

Add the provider at your root to initialize the SDK.

:::code-group

```tsx [With expo-router]
// app/_layout.tsx
import { OpenfortProvider } from "@openfort/react-native";
import { Slot } from "expo-router";

export default function RootLayout() {

  return (
    <>
      {/* Your other providers */}
        <OpenfortProvider
          publishableKey="YOUR_PROJECT_PUBLISHABLE_KEY"
          walletConfig={{
            shieldPublishableKey: "YOUR_SHIELD_PUBLISHABLE_KEY",
            createEncryptedSessionEndpoint: "https://your-backend.com/api/protected-create-encryption-session"
          }}
        >
          {/* Render nested routes */}
          <Slot />
        </OpenfortProvider>
      {/* Your other providers */}
    </>
  );
}
```

```tsx [Without expo-router]
// App.tsx

import { OpenfortProvider } from "@openfort/react-native";
import { View, Text, StyleSheet } from "react-native";

export default function App() {

  return (
    <>
      {/* Your other providers */}
        <OpenfortProvider
          publishableKey="YOUR_PROJECT_PUBLISHABLE_KEY"
          walletConfig={{
            shieldPublishableKey: "YOUR_SHIELD_PUBLISHABLE_KEY",
            createEncryptedSessionEndpoint: "https://your-backend.com/api/protected-create-encryption-session"
          }}
        >
          {/* Your app content */}
          <View style={styles.containerCentered}>
            <Text style={styles.heading}>Hello, World!</Text>
          </View>
        </OpenfortProvider>
      {/* Your other providers */}
    </>
  );
}

const styles = StyleSheet.create({
  containerCentered: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
  },
  heading: {
    fontSize: 18,
  },
});
```

:::

## You can now start using Openfort!

Advance to [this next guide](/docs/products/embedded-wallet/react-native/quickstart/automatic) to get the API keys and create your first wallet.

::::

## SDK Exports

The React Native SDK exports the following:

| Export | Description |
|--------|-------------|
| `OpenfortProvider` | Root provider component |
| `AuthBoundary` | Auth state-based rendering component |
| `useOpenfort` | SDK initialization state hook |
| `useOpenfortClient` | Direct access to Openfort client |
| `useUser` | Current user and access token hook |
| `useEmailAuth` | Email/password authentication hook |
| `useEmailAuthOtp` | Email OTP authentication hook |
| `usePhoneAuthOtp` | Phone OTP authentication hook |
| `useOAuth` | OAuth provider authentication hook |
| `useGuestAuth` | Guest authentication hook |
| `useWalletAuth` | SIWE wallet authentication hook |
| `useSignOut` | Sign out hook |
| `useEmbeddedEthereumWallet` | Ethereum wallet management hook |
| `useEmbeddedSolanaWallet` | Solana wallet management hook |
| `usePasskeyPrfSupport` | Check if device supports passkey PRF (Android 14+, iOS 18+) |

### Re-exported from `@openfort/openfort-js`

| Export | Description |
|--------|-------------|
| `OpenfortClient` | Core Openfort class (alias for `Openfort`) |
| `OpenfortEvents` | Event name type (use `openfortEvents` for the emitter instance) |
| `openfortEvents` | Global event emitter |
| `OAuthProvider` | OAuth provider enum |
| `AccountTypeEnum` | Account type enum (SMART\_ACCOUNT, EOA) |
| `ChainTypeEnum` | Chain type enum (EVM, SVM) |
| `EmbeddedState` | Embedded wallet state enum |
| `RecoveryMethod` | Recovery method enum (AUTOMATIC, PASSWORD, PASSKEY) |
| `RecoveryParams` | Recovery parameters type |
| `OpenfortError` | Base error class |
| `AuthInitPayload` | Authentication initialization payload type |
| `AuthResponse` | Authentication response type |
| `EmbeddedAccount` | Embedded account type |
| `OpenfortConfiguration` | SDK configuration type |
| `OpenfortEventMap` | Event map type for event emitter |
| `Provider` | Provider type |
| `ShieldConfiguration` | Shield configuration type |
| `SignedMessagePayload` | Signed message payload type |
| `ThirdPartyOAuthProvider` | Third-party OAuth provider type |

For detailed component documentation, see the [Components](/docs/products/embedded-wallet/react-native/components) section.
