Get started (React Native SDK)
Prerequisites
Expo or expo-modules
Our SDK is built as an Expo Module, which means it requires the Expo Modules runtime to be present in your app. This applies to bare React Native apps as well as Expo-managed projects, but this does not mean you need to migrate your app to Expo. Expo officially supports installing Expo Modules into an existing bare React Native app; see Installing Expo modules in an existing React Native project on the Expo docs.
Our SDK ships native iOS and Android code (the IdensicMobileSDK pod and SumSub Specs on iOS, the SumSub Maven repository on Android). Expo Go can only load JavaScript against its prebuilt native shell, so it cannot load any third-party native modules - including ours. To run and test your app you must build a custom client that includes the SDK's native dependencies. See Test your app.
Compatibility
- React Native: ~0.81
- React: ~19
- Expo: ~54
- Min iOS: 15.1+
- Min Android: 24+
Install Expo Modules
If expo-modules-core is already installed and your native projects compile successfully, skip this step.
Having an Expo package in JavaScript is not sufficient - the native wiring must also be in place.
Run the following in the root of your React Native project:
npx install-expo-modules
This wires up the Expo Modules runtime into your native iOS (AppDelegate) and Android (MainApplication) entry points. If your project deviates significantly from a standard React Native setup, follow the manual installation guide on the Expo docs instead.
Common symptoms of a missing or incomplete Expo Modules installation:
- iOS: build error
No such module 'ExpoModulesCore' - Android: build error
project :expo-modules-core not found
If you see either of these after installing the SDK, revisit this step.
Install the SDK
Install expo (a peer dependency) and the SDK:
- npm
- yarn
npm install expo @weavr-io/secure-components-react-native
yarn add expo @weavr-io/secure-components-react-native
iOS native config
Xcode 26 (any 26.x) currently breaks React Native iOS builds via a consteval mismatch in the fmt Pod that React Native pulls in transitively. The errors look like cryptic compile failures inside fmt and aren't specific to our SDK. If you're on Xcode 26, apply the Podfile workaround in Xcode 26 iOS build failure before running pod install. Tracking issue: expo/expo#44229.
Podfile
Add the following sources before the target block in ios/Podfile. The CocoaPods CDN source is the default but some Podfiles declare it explicitly. Add the SumSub Specs source alongside it. Do not remove any existing sources:
source 'https://cdn.cocoapods.org/'
source 'https://github.com/SumSubstance/Specs.git'
Add the following inside the target block:
pod 'IdensicMobileSDK', '~> 1.41.0'
Then run:
cd ios && pod install
Info.plist permissions
Add only the permissions your integration actually triggers - adding unused permissions can cause issues during App Store review.
<!-- Required for KYC document capture -->
<key>NSCameraUsageDescription</key>
<string>Allow $(PRODUCT_NAME) to access your camera</string>
<!-- Required for KYC video verification -->
<key>NSMicrophoneUsageDescription</key>
<string>Allow $(PRODUCT_NAME) to access your microphone</string>
<!-- Required for KYC document upload from library -->
<key>NSPhotoLibraryUsageDescription</key>
<string>Allow $(PRODUCT_NAME) to access your photos</string>
<!-- Required for KYC location verification -->
<key>NSLocationWhenInUseUsageDescription</key>
<string>Allow $(PRODUCT_NAME) to access your location</string>
<!-- Required for Face ID authentication (iOS only - not needed for Touch ID) -->
<key>NSFaceIDUsageDescription</key>
<string>Allow $(PRODUCT_NAME) to use Face ID for login</string>
Android native config
Maven repositories
Add the following Maven repositories alongside your existing ones - do not remove google() or mavenCentral().
If your project uses the classic android/build.gradle, add them inside the allprojects > repositories block:
maven { url "https://maven.sumsub.com/repository/maven-public/" }
jcenter() // legacy repo - only included because some transitive dependencies still require it
maven {
url "https://gitlab.okaythis.com/api/v4/projects/15/packages/maven"
name "GitLab"
}
maven { url 'https://storage.googleapis.com/download.flutter.io' }
If your project uses Gradle's dependencyResolutionManagement in android/settings.gradle (Gradle 7 or later), add these repositories under the repositories {} block there instead.
Bouncy Castle conflict
Add the following to android/app/build.gradle to resolve a Bouncy Castle dependency conflict:
configurations.configureEach {
resolutionStrategy.eachDependency { details ->
if (details.requested.group == 'org.bouncycastle') {
details.useTarget 'org.bouncycastle:bcprov-jdk15to18:1.68'
}
}
}
AndroidManifest.xml
Add the tools namespace to your AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
Only add tools:replace="android:allowBackup" to the <application> tag if your build fails with a manifest merger conflict related to android:allowBackup:
<application
tools:replace="android:allowBackup"
...>
Add the following permission only if your integration uses the microphone (for example, KYCKYC Know Your Customer - the identity verification process for consumer identities. This process allows you to seamlessly and securely verify your user's identity. Weavr will ask users to submit the necessary information and documentation so that they can get approved by financial providers. video verification):
<uses-permission android:name="android.permission.RECORD_AUDIO" />
Managed Expo apps
If your project uses a managed Expo workflow, expo-modules-core is already in place - skip the Install Expo Modules step. Configure the SDK plugin so Expo applies the iOS and Android native configuration during prebuild.
Export your asset path:
const path = require("path");
module.exports = {
assets: ["./assets/fonts/"],
};
Add the SDK plugin and expo-build-properties to your Expo config:
plugins: [
[
'@weavr-io/secure-components-react-native',
{
permissions: {
"photosPermission": "Allow $(PRODUCT_NAME) to access photos in your library to perform KYC",
"cameraPermission": "Allow $(PRODUCT_NAME) to open the camera to perform KYC",
"microphonePermission": "Allow $(PRODUCT_NAME) to use the microphone to perform KYC",
"locationWhenInUseUsage": "Allow $(PRODUCT_NAME) to get access to your location while in use to perform KYC",
"faceIdUsage": "Allow $(PRODUCT_NAME) to get access to Face ID to login with biometrics"
}
} as WithWeavrSDKConfig
],
[
'expo-build-properties',
{
android: {
compileSdkVersion: 35,
targetSdkVersion: 35,
buildToolsVersion: '35.0.0',
},
ios: {
deploymentTarget: '15.1',
},
},
],
],
Biometric authentication uses the Firebase push notification service, so you may also need to add Firebase React Native dependencies. Follow the React Native Firebase installation guide to add and configure google-services.json (Android) and GoogleService-Info.plist (iOS).
Test your app
You cannot run an app that uses our SDK in Expo Go - it lacks the native modules our SDK depends on. Test against a build that bundles the SDK's native code instead. Choose the tab that matches your project setup:
- Bare React Native
- Managed Expo
Build and install your app on a simulator or device the standard React Native way. Metro then connects automatically:
npx react-native run-ios
# or
npx react-native run-android
You only need to rebuild when native dependencies change (for example after a pod install or a Gradle change). JavaScript changes hot-reload through Metro.
Build a custom development client with expo-dev-client, install it on your target device or simulator, then point it at your local Metro bundler.
Build the dev client:
# Local build (requires Xcode for iOS, Android SDK for Android)
npx eas build --profile development --local
# Or cloud build via EAS
npx eas build --profile development
Install the resulting .app, .ipa, or .apk, then start Metro:
npx expo start --dev-client
The dev client launches and connects to Metro the same way Expo Go would, but with our SDK's native code linked in.
Rebuild the dev client whenever you change native config (for example, the SDK plugin options in app.config.ts, permission strings, or expo-build-properties). Pure JavaScript changes do not require a rebuild.
Notes
- Native dependencies are required for every client. The Expo Modules runtime, the iOS Podfile sources and
IdensicMobileSDKpod, and the Android Maven repositories are required by every client to resolve the SDK's native dependencies - regardless of which features you use. - Permissions are only needed for the features you use. The
Info.plistpermission strings andandroid.permission.RECORD_AUDIOare only required if your integration triggers the corresponding OS prompts. Do not add permissions for features you don't use. - You do not need to use Expo prebuild or restructure your app as an Expo app to use this SDK in a bare React Native project.
Set App Check token
To securely link Firebase App Check protection with our SDK components, you must retrieve and store the App Check token before sensitive operations like login or biometric enrollment.
You can use React Native Firebase to fetch your token
The setAppCheckToken() method securely injects the App Check token into the SDK.
setAppCheckToken("");
The method setAppCheckToken() returns a boolean:
true: the token was stored successfully in the SDK.false: the App Check token was not accepted - ensure the token is valid and properly formatted.
Initialize the SDK
After the libraries are in place, you can initialize our component SDK by:
import {
initializeUXComponents,
initializePSA,
} from "@weavr-io/secure-components-react-native";
initializeUXComponents(env, WEAVR_UI_KEY)
.then((res) => console.log(res))
.catch((e) => console.log(e));
//if you are using Weavr biometric, you need to initialize the biometric solution too:
initializePSA(env)
.then((res) => console.log(res))
.catch((e) => console.log(e));
Platform-specific styling props
The SDK components use platform-specific styling props that align with the native capabilities of iOS and Android. This is similar to how React Native itself has platform-specific props (like showsVerticalScrollIndicator on iOS vs Android).
SecurePasscodeTextField and SecureSegmentedPasscodeTextField must not be used as an authentication input on iOS - Apple does not permit passcodes as an authentication method. iOS columns appear in the tables in the following sections only for completeness; render passcode components on Android only and use the password component for iOS authentication. See Login components for details.
The following tabs show the correct props for each platform:
- Android
- iOS
For SecureSegmentedPasscodeTextField on Android, use these props:
import { SecureSegmentedPasscodeTextField } from '@weavr-io/secure-components-react-native';
<SecureSegmentedPasscodeTextField
ref={segmentedPasscodeRef}
style={styles.input}
// ✅ Android styling props
enableBorder={true}
activeFieldBorderColor="red"
inactiveFieldBorderColor="yellow"
backgroundViewColor="green"
segmentHeight={64}
segmentSpacing={16}
minimumWidth={100}
textSize="18"
// Events
onTextChanges={handleTextChange}
onTextEntryComplete={handleOnTextEntryComplete}
/>
For SecureSegmentedPasscodeTextField on iOS, use these props. As noted in the preceding warning, do not use the passcode component as an authentication input on iOS - these props apply only when you render the component in a non-authentication context:
import { SecureSegmentedPasscodeTextField } from '@weavr-io/secure-components-react-native';
<SecureSegmentedPasscodeTextField
ref={segmentedPasscodeRef}
style={styles.input}
// ✅ iOS styling props
enableBorder={true}
activeFieldBorderColor="red"
inactiveFieldBorderColor="yellow"
backgroundViewColor="green"
segmentSpacing={16}
minimumWidth={100}
textSize="18"
placeholder="••••"
fieldBackgroundColor="#ffffff"
fontStyle={{
fontFamily: 'Lobster-Regular',
fontSize: 16,
color: '#8080cc',
}}
// Events
onTextChanges={handleTextChange}
onTextEntryComplete={handleOnTextEntryComplete}
/>
Platform differences
Different props are available on each platform to match native styling patterns:
SecureSegmentedPasscodeTextField
| Prop | iOS | Android | Notes |
|---|---|---|---|
| enableBorder | ✅ | ✅ | Both platforms |
| activeFieldBorderColor | ✅ | ✅ | Both platforms |
| inactiveFieldBorderColor | ✅ | ✅ | Both platforms |
| backgroundViewColor | ✅ | ✅ | Both platforms |
| textSize | ✅ | ✅ | Both platforms |
| segmentSpacing | ✅ | ✅ | Both platforms |
| minimumWidth | ✅ | ✅ | Both platforms |
| placeholder | ✅ | - | iOS-specific |
| fieldBackgroundColor | ✅ | - | iOS-specific |
| fontStyle | ✅ | - | iOS-specific |
| segmentHeight | - | ✅ | Android-specific |
| segmentCount | - | ✅ | Android-specific |
SecurePasscodeTextField
This component currently has different styling APIs on each platform:
iOS: supports placeholder, placeholderTextColor, background, textSize, and more
Android: use SecureSegmentedPasscodeTextField for rich styling options
Next steps
With the SDK installed and initialized, you can integrate components:
- Login components - sign users in securely
- Biometrics - biometric login and step-up authentication
- Card components - display PANPAN Primary Account Number - the long card number (typically 16 digits) printed or embossed on a payment card and used to identify the card on the payment network. Weavr never returns the raw PAN to your client; `GET /managed_cards/{id}` returns the PAN in tokenized form as `cardNumber`, and the value is only detokenized inside a Secure UI card-number component (a sandboxed iframe on the web, a secure native view on mobile)., CVVCVV Card Verification Value - the 3-digit security code printed on a payment card, used to authenticate card-not-present transactions. Weavr returns CVV in tokenized form on `GET /managed_cards/{id}` (with a stepped-up token); the value is only detokenized inside the SDK's secure CVV display component., and PINPIN Personal Identification Number - the numeric code a cardholder enters to authorize chip-and-PIN purchases and ATM withdrawals. PIN is only present on physical managed cards. Weavr returns it tokenized on `GET /managed_cards/{id}` (with a stepped-up token), and the SDK detokenizes it inside a secure PIN display component.
- KYC components - identity verification flows
- Push provisioning - add cards to Apple Wallet and Google Wallet