Plaid React Native SDK
The `react-native-plaid-link-sdk` is the official client-side SDK for integrating Plaid Link into React Native applications, enabling users to securely connect their financial accounts to Plaid's services. As of version 12.8.0, it provides a programmatic API for initializing and opening the Link flow, including an optional preloading feature (introduced in v11.6.0) designed to reduce latency for users. The SDK also offers a declarative `PlaidLink` component and robust callbacks for managing Link success and exit events. It handles platform-specific integrations for iOS (via CocoaPods) and Android (via Gradle). Plaid actively maintains this SDK, with major versions frequently introducing updates to the Link flow or API integration patterns, ensuring compatibility with the latest Plaid Link features and security standards. Developers should consult the official documentation for specific version-dependent integration details.
Common errors
-
Plaid Link initialization failed: Invalid link_token
cause The provided `link_token` is expired, malformed, or has already been used.fixEnsure your backend generates a new `link_token` for each Plaid Link session using the `/link/token/create` endpoint and that your React Native app is fetching this fresh token before calling `create` or `open`. -
Error: Failed to install CocoaPods dependencies
cause Automatic linking of iOS dependencies via CocoaPods failed after `npm install`.fixNavigate to your iOS project directory (`cd ios`) and manually run `bundle install && bundle exec pod install` to install dependencies. -
Connection to OAuth institution fails on Android device/emulator.
cause The Android application's package name is not registered in the Plaid Dashboard, preventing successful OAuth redirect handling.fixLog in to your Plaid Dashboard, navigate to 'Team Settings' -> 'API' and add your app's Android package name (e.g., `com.yourcompany.yourapp`) to the 'Android Package Names' list. -
Plaid Link doesn't open or crashes on Android, or shows `android.view.InflateException`
cause Your Android project's `compileSdkVersion` is not set to `33`, which is a requirement for recent versions of the SDK.fixOpen your `android/app/build.gradle` file and set `compileSdkVersion 33`.
Warnings
- breaking Starting with v11.6.0, the recommended integration pattern shifted to using `create()` for preloading the Link experience, followed by `open()` to launch it. Previous versions typically relied solely on `open()` or the `PlaidLink` component directly without a distinct preloading step. Applications upgrading from versions older than 11.6.0 must adapt to this new `create` then `open` flow.
- gotcha For Android, your project's `compileSdkVersion` must be `33` to ensure compatibility and proper functioning of the Plaid React Native SDK. Mismatched SDK versions can lead to build failures or runtime issues.
- gotcha When developing for Android, you must register your application's Android package name (e.g., `com.yourcompany.yourapp`) in the Plaid Dashboard. Failure to do so will prevent the successful connection to OAuth institutions, which include most major banks.
- gotcha The `link_token` required by the SDK is a short-lived, single-use token that must be generated on your backend server using the `/link/token/create` endpoint of the Plaid API. It should never be generated client-side or hardcoded.
Install
-
npm install react-native-plaid-link-sdk -
yarn add react-native-plaid-link-sdk -
pnpm add react-native-plaid-link-sdk
Imports
- open
const { open } = require('react-native-plaid-link-sdk');import { open } from 'react-native-plaid-link-sdk'; - create
const { create } = require('react-native-plaid-link-sdk');import { create } from 'react-native-plaid-link-sdk'; - PlaidLink
import PlaidLink from 'react-native-plaid-link-sdk';
import { PlaidLink } from 'react-native-plaid-link-sdk'; - LinkSuccess, LinkExit
import type { LinkSuccess, LinkExit } from 'react-native-plaid-link-sdk';
Quickstart
import React, { useEffect, useState } from 'react';
import { Button, View, Text, Platform, Alert } from 'react-native';
import {
open,
create,
dismissLink,
LinkSuccess,
LinkExit,
LinkTokenConfiguration,
LinkOpenProps,
LinkIOSPresentationStyle,
LinkLogLevel,
} from 'react-native-plaid-link-sdk';
// IMPORTANT: In a real application, 'YOUR_GENERATED_PLAID_LINK_TOKEN'
// must be fetched from your backend server. This token is short-lived.
// Refer to Plaid's /link/token/create documentation.
const GENERATED_LINK_TOKEN = 'YOUR_GENERATED_PLAID_LINK_TOKEN';
const PlaidLinkIntegration = () => {
const [linkToken, setLinkToken] = useState<string | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
// Simulate fetching a link token from your backend.
// Replace this with an actual API call to your server that generates the token.
const fetchLinkToken = async () => {
try {
// Example (replace with your actual backend endpoint):
// const response = await fetch('https://your-backend.com/create_plaid_link_token');
// const data = await response.json();
// setLinkToken(data.link_token);
if (GENERATED_LINK_TOKEN !== 'YOUR_GENERATED_PLAID_LINK_TOKEN') {
setLinkToken(GENERATED_LINK_TOKEN);
} else {
Alert.alert(
'Missing Link Token',
"Please replace 'YOUR_GENERATED_PLAID_LINK_TOKEN' with a valid token from your backend. Link will not open without it."
);
}
} catch (error) {
console.error('Failed to fetch link token:', error);
Alert.alert('Error', 'Could not fetch Plaid Link token.');
}
setLoading(false);
};
fetchLinkToken();
}, []);
useEffect(() => {
if (linkToken) {
// For SDK versions >= 11.6.0, it's recommended to preload Link.
const tokenConfiguration: LinkTokenConfiguration = {
token: linkToken,
noLoadingState: false, // Set to true to hide the native activity indicator
};
create(tokenConfiguration);
}
}, [linkToken]);
const handleOpenLink = () => {
if (!linkToken) {
Alert.alert('Error', 'Plaid Link token is not available yet.');
return;
}
const openProps: LinkOpenProps = {
onSuccess: (success: LinkSuccess) => {
console.log('Plaid Link Success:', success);
// Send success.public_token to your backend for exchange with an access_token
Alert.alert('Link Success', `Account linked! Public Token: ${success.public_token}`);
},
onExit: (linkExit: LinkExit) => {
console.log('Plaid Link Exit:', linkExit);
if (linkExit.error) {
console.error('Plaid Link Error:', linkExit.error);
Alert.alert('Link Exit Error', `Code: ${linkExit.error.error_code}, Message: ${linkExit.error.display_message}`);
}
dismissLink(); // Ensure Link view is dismissed, especially on iOS.
},
iOSPresentationStyle: LinkIOSPresentationStyle.MODAL, // Or FULL_SCREEEN
logLevel: LinkLogLevel.ERROR,
};
open(openProps);
};
if (loading) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Loading Plaid Link Token...</Text>
</View>
);
}
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Button
title="Open Plaid Link"
onPress={handleOpenLink}
disabled={!linkToken}
/>
{!linkToken && (
<Text style={{ marginTop: 10, color: 'red' }}>
Please provide a valid Plaid Link token.
</Text>
)}
</View>
);
};
export default PlaidLinkIntegration;