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

# Overview

Fingerprint React Native is an official [open-source](https://github.com/fingerprintjs/react-native) library for projects written in React Native for iOS and Android platforms. This library allows developers to use Fingerprint capabilities in the React Native context. View our [React Native quickstart](/docs/react-native-quickstart) for a step-by-step guide to get started.

<Note>
  Upgrading from SDK v3? See the [migration guide](/docs/react-native-migrating-from-v3-to-v4) for a full list of breaking changes, including the package rename from `@fingerprintjs/fingerprintjs-pro-react-native` to `@fingerprint/react-native`.
</Note>

## Requirements

The React Native SDK uses the [Android](/docs/native-android-integration) and [iOS](/docs/ios) SDKs under the hood, and it requires React Native 0.80, so the effective minimum versions are:

* React Native 0.80 or higher, with the [New Architecture](https://reactnative.dev/architecture/landing-page) enabled. The Old Architecture isn't supported. This floor comes from the SDK's use of React Native's [Strict TypeScript API](https://reactnative.dev/docs/strict-typescript-api).
* Android 7.0 (API level 24+) or higher, as required by React Native 0.80
* iOS 15.1 or higher (or tvOS 15 or higher), Swift 5.9 or higher
* Expo SDK 54 or higher. The SDK isn't usable in Expo Go because it includes custom native code; use a [development build](https://docs.expo.dev/develop/development-builds/introduction/) instead.

## How to install

### 1. Install the package using your favorite package manager:

<CodeGroup>
  ```shell NPM theme={"theme":"github-dark-dimmed"}
  npm install @fingerprint/react-native --save
  ```

  ```shell Yarn theme={"theme":"github-dark-dimmed"}
  yarn add @fingerprint/react-native
  ```

  ```shell PNPM theme={"theme":"github-dark-dimmed"}
  pnpm add @fingerprint/react-native
  ```
</CodeGroup>

### 2. Configure dependencies:

#### Expo setup

1. Add the config plugin to your `app.json` or `app.config.js`:

```json app.json theme={"theme":"github-dark-dimmed"}
{
  "expo": {
    "plugins": ["@fingerprint/react-native"]
  }
}
```

2. Rebuild your native projects:

```shell theme={"theme":"github-dark-dimmed"}
npx expo prebuild --clean
```

<Note>
  Because the SDK includes custom native code, it doesn't work in Expo Go. Use `npx expo run:ios`/`run:android` or an [EAS development build](https://docs.expo.dev/develop/development-builds/introduction/).
</Note>

#### Bare React Native setup

1. Configure iOS dependencies (if developing on iOS)

```shell theme={"theme":"github-dark-dimmed"}
cd ios && pod install
```

2. Configure Android dependencies (if developing on Android)

Add the repositories to your Gradle configuration file. The location for these additions depends on your project's structure and the Gradle version you're using:

You likely manage repositories in the `dependencyResolutionManagement` block in `{rootDir}/android/settings.gradle`. Add the Maven repositories in this block:

```groovy Groovy theme={"theme":"github-dark-dimmed"}
dependencyResolutionManagement {
  repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
  repositories {
    google()
    mavenCentral()
    maven {
      url("https://maven.fpregistry.io/releases") // Add this
    }
  }
}
```

### 3. SPM support (experimental)

On React Native 0.87 and higher, you can link iOS dependencies with Swift Package Manager instead of CocoaPods:

```shell theme={"theme":"github-dark-dimmed"}
cd ios && npx react-native spm --deintegrate
```

SPM support is experimental. If you hit issues, fall back to `pod install`.

### Web support

If your app also targets web (for example with React Native Web), install [`@fingerprint/agent`](https://www.npmjs.com/package/@fingerprint/agent) as an optional peer dependency:

```shell theme={"theme":"github-dark-dimmed"}
npm install @fingerprint/agent@^4.1.3 --save
```

## Usage

Configure the SDK by wrapping your application in `FingerprintProvider`.

```javascript JavaScript theme={"theme":"github-dark-dimmed"}
// src/index.js
import React from 'react';
import { AppRegistry } from 'react-native';
import { FingerprintProvider } from '@fingerprint/react-native';
import App from './App';
import { name as appName } from './app.json';

const WrappedApp = () => (
  <FingerprintProvider apiKey={'PUBLIC_API_KEY'} region={'eu'}>
    <App />
  </FingerprintProvider>
)

AppRegistry.registerComponent(appName, () => WrappedApp);
```

Use the `useVisitorData` hook in your components to perform visitor identification and get the data. `getData` always throws on error, and `immediate` defaults to `false` so the SDK doesn't fetch eagerly on mount (native platforms don't cache results, so eager fetches cost API calls).

```javascript JavaScript theme={"theme":"github-dark-dimmed"}
// src/App.js
import React from 'react'
import {Button, SafeAreaView, Text, View} from 'react-native'
import {useVisitorData} from '@fingerprint/react-native'

export default function App() {
  const {isLoading, isFetched, error, data, getData} = useVisitorData()

  return (
    <SafeAreaView>
      <View style={{ margin: 8 }}>
        <Button title='Reload data' onPress={() => getData().catch(() => {})} />
        {isLoading ? (
          <Text>Loading...</Text>
        ) : (
          <>
            <Text>Visitor ID: {isFetched ? data?.visitor_id : undefined}</Text>
            <Text>Full visitor data:</Text>
            <Text>{error ? error.message : JSON.stringify(data, null, 2)}</Text>
          </>
        )}
      </View>
    </SafeAreaView>
  )
}
```

### API client

To integrate outside of a React component, call `start()` once to create a client. `start()` returns the client synchronously; only `get()` is asynchronous.

```javascript JavaScript theme={"theme":"github-dark-dimmed"}
import { start } from '@fingerprint/react-native';

const fp = start({ apiKey: 'PUBLIC_API_KEY', region: 'eu' });
const data = await fp.get({ tags: { action: 'login' } });

console.log(data.visitor_id, data.event_id);
```

### useFingerprint

Use `useFingerprint()` inside `FingerprintProvider` to read the same client from context, for example to call `get()` from an event handler instead of relying on the hook's automatic fetch:

```javascript JavaScript theme={"theme":"github-dark-dimmed"}
import { useFingerprint } from '@fingerprint/react-native';

function LoginButton() {
  const fp = useFingerprint();

  const handleLogin = async () => {
    const data = await fp.get({ tags: { action: 'login' } });
    console.log(data.visitor_id);
  };

  return <Button title="Log in" onPress={handleLogin} />;
}
```

## Response format

`useVisitorData` and `get()` resolve with a flat object that matches the [Server API v4](/reference/server-api-get-event) event format:

```typescript theme={"theme":"github-dark-dimmed"}
interface FingerprintResponse {
  visitor_id?: string; // `undefined` if zero-trust mode is enabled
  event_id: string;
  suspect_score?: number; // only present when Smart Signals are enabled
  sealed_result: string | null;
  cache_hit?: boolean; // web only, set when caching is configured; always undefined on native platforms
}
```

The SDK no longer supports `extendedResponseFormat` or the nested extended fields (`ipLocation`, `firstSeenAt`, `osName`, and similar); it always returns this flat format. Use [IP Geolocation](/docs/smart-signals-reference#ip-geolocation) and the other Smart Signals for the data those fields used to carry.

## Error handling

All identification failures are instances of `FingerprintError`, with `name`, `code`, and `event_id` fields. Use the `isFingerprintError` type guard to identify them, and discriminate behavior on `error.code`:

```javascript JavaScript theme={"theme":"github-dark-dimmed"}
import { isFingerprintError } from '@fingerprint/react-native';

try {
  const data = await getData();
} catch (error) {
  if (isFingerprintError(error)) {
    console.log(error.code, error.event_id);
  }
}
```

`code` is a string union that groups into:

* Server / API v4 error codes, returned by the Fingerprint API itself
* Native client-side error codes, raised by the underlying Android or iOS SDK
* Web client-side error codes, raised by the underlying `@fingerprint/agent` client

Treat `code` as open to unknown strings; handle the codes you care about and fall back to generic handling for the rest.

## Linking and tagging

Pass `tags`, `linkedId`, and `timeout` together as a single options object:

```javascript JavaScript theme={"theme":"github-dark-dimmed"}
const data = await getData({
  tags: { action: 'checkout' },
  linkedId: 'user-1234',
  timeout: 5000,
});
```

## Proximity detection

Location-based options are grouped by platform:

```javascript JavaScript theme={"theme":"github-dark-dimmed"}
<FingerprintProvider
  apiKey="PUBLIC_API_KEY"
  region="eu"
  android={{ allowUseOfLocationData: true, locationTimeoutMillis: 2000 }}
  ios={{ allowUseOfLocationData: true }}
>
  <App />
</FingerprintProvider>
```

## Caching

Caching is web-only and disabled by default. Enable it via the `web` option:

```javascript JavaScript theme={"theme":"github-dark-dimmed"}
<FingerprintProvider
  apiKey="PUBLIC_API_KEY"
  region="eu"
  web={{ cache: { storage: 'sessionStorage', duration: 3600 } }}
>
  <App />
</FingerprintProvider>
```

## Documentation

You can find the full documentation in the official [GitHub repository](https://github.com/fingerprintjs/react-native).

### Limitations

* Fingerprint [request filtering](/docs/request-filtering) is not supported right now. Allowed and forbidden origins cannot be used.
