npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@veryai/react-native-sdk

v1.0.66

Published

React Native wrapper for Very SDK - Palm biometrics verification

Downloads

1,354

Readme

React Native SDK Integration

Full documentation: https://very.org/docs/native-sdk/integration

Installation

npm install @veryai/react-native-sdk

Using Expo? The steps below are for bare React Native — see Expo instead.

For iOS, install the native dependency:

cd ios && pod install

Add camera permission to Info.plist:

<key>NSCameraUsageDescription</key>
<string>Camera access is needed for palm biometric verification.</string>

Published on npm.

Expo

The SDK works with the Expo managed workflow. You never need to run pod install yourself or commit ios/ and android/expo prebuild and EAS Build do that for you.

Two things are non-negotiable:

  • A custom dev client. The SDK carries native Swift/Kotlin code and the PalmID native matcher, so Expo Go cannot load it. Build a dev client with npx expo run:ios / npx expo run:android, or eas build --profile development.
  • A physical device. Palm capture needs a real camera and the native matcher; simulators and emulators will not work.

There is no config plugin to install — the package does not ship one, and does not need one.

iOS

Declare the camera usage string in app.json. expo prebuild writes it into the generated Info.plist, so this is the only native configuration the host app owes the SDK:

{
  "expo": {
    "ios": {
      "infoPlist": {
        "NSCameraUsageDescription": "Camera access is required for palm biometric verification."
      }
    }
  }
}

Android

Nothing to configure. The SDK's AAR manifest already declares CAMERA, INTERNET, and ACCESS_NETWORK_STATE, and manifest merge folds them into the host app.

If you forget the usage string

authenticate() fails on iOS with error 6105 rather than proceeding, because AVCaptureDevice.requestAccess would otherwise terminate the process unrecoverably. How that surfaces depends on the build configuration:

| Build | What you see | | ----- | ------------ | | Release | the 6105 error through the normal SDK error callback | | Debug (including a default dev client) | an assertion trap, plus the same message in the log |

A dev client is a Debug build by default, so during development expect the trap. Either way the fix is the same: add the key to app.json and rebuild — a JS reload is not enough, since the value lives in the compiled Info.plist.

There is no Android equivalent of 6105; Android grants camera access through the runtime permission model instead.

Slim mode is not available in a pure managed workflow

Switching to slim asset loading edits ios/Podfile and android/app/build.gradle, both of which are prebuild output that gets regenerated. Using it means either committing the native directories or writing a config plugin with dangerous mods. Stay on the default bundled mode unless binary size is a hard constraint.

Reference project

examples/ExpoNewArchExample is a working managed setup (Expo SDK 54, RN 0.81, New Architecture). CI runs expo prebuild --clean against it and builds both platforms natively on every PR that touches the SDK or the examples.

Asset Loading: Bundled vs Slim

The SDK ships with the palm-recognition native asset bundled inside it by default — your app works offline, no first-scan download wait. If you'd rather keep your binary small and have the SDK fetch the asset from CDN on first scan, you can opt into slim mode per platform.

| Mode | Adds to app size | First-scan UX | Works offline | | ------ | ----------------------------------------- | ---------------------------- | ------------- | | Bundled (default) | ~18 MB per ABI (Android), ~8 MB (iOS) | instant | yes | | Slim | nothing | one-time download (5–15 s) | no (first scan only) |

Cached assets persist across app launches; the download only happens once.

iOS — switching to slim

Step 1 — disable RN auto-linking for this package only. Add or edit react-native.config.js at your project root:

module.exports = {
  dependencies: {
    '@veryai/react-native-sdk': {
      platforms: { ios: null },
    },
  },
};

Step 2 — declare the slim subspec explicitly in ios/Podfile inside your app target:

target 'YourApp' do
  config = use_native_modules!
  use_react_native!(...)

  pod 'veryai-react-native-sdk/Core',
      :path => '../node_modules/@veryai/react-native-sdk'
end

Step 3:

cd ios && pod install

To go back to bundled, delete the react-native.config.js entry and the pod 'veryai-react-native-sdk/Core' line, then pod install again.

Android — switching to slim

In android/app/build.gradle (the app module, not the project root), add:

android {
    packaging {
        jniLibs {
            excludes += '**/libPalmAPISaas.so'
        }
    }
}

This filters the bundled .so out at packaging time. The runtime falls through to CDN download.

Verifying which mode you're in

iOS — after pod install:

grep -c "VerySDK_BundledModel\|packed_data" ios/Pods/Pods.xcodeproj/project.pbxproj
# > 0 → bundled, 0 → slim

Android — after a build:

unzip -l android/app/build/outputs/apk/debug/app-debug.apk | grep libPalmAPISaas
# matches → bundled, no output → slim

CDN endpoints (slim mode)

The SDK tries the primary CDN first and falls back automatically. Allowlist both hostnames if your network has egress restrictions.

| Asset | Primary | Backup | | -------------------------------- | ------------------------------------------------ | ------------------------------------------------------- | | Android libPalmAPISaas.so (per ABI) | assets.very.org/sdk/data/<abi>/... | r2.assets.very.org/sdk/v1/<abi>/... | | iOS packed_data.bin | assets.very.org/sdk/data/packed_data.bin | r2.assets.very.org/sdk/v1/packed_data.bin |

Create an SDK App and Key

Create a Palm Verification SDK app in the Developer Portal and copy its SDK key. Native SDK integrations do not use an OAuth client ID, client secret, or authorization-code exchange.

Enroll a New User

Pass undefined for userId to register a new user. The SDK opens a consent screen, collects the user's email, then guides them through a palm scan.

import { VerySDK } from "@veryai/react-native-sdk";

const supported = await VerySDK.isSupported();
if (!supported) {
  console.warn("Device not supported");
  return;
}

const result = await VerySDK.authenticate({
  sdkKey: "your_sdk_key",
  userId: undefined, // undefined = new enrollment
  themeMode: "dark",
  presentationStyle: "fullScreen",
  clientReferenceId: "gate-withdrawal-42", // your transaction/session ID
});

if (result.isSuccess) {
  console.log("User ID:", result.userId);
  console.log("User status:", result.userStatus);
  console.log("Signed token:", result.signedToken);
} else {
  console.error("Error:", result.error, result.errorMessage);
}

Verify an Existing User

Pass the user's ID from a previous enrollment to verify their identity.

const result = await VerySDK.authenticate({
  sdkKey: "your_sdk_key",
  userId: "vu-1ed0a927-...", // from previous enrollment
  themeMode: "dark",
});

if (result.isSuccess) {
  console.log("Verified user:", result.userId);
  console.log("User status:", result.userStatus);
  console.log("Signed token:", result.signedToken);
}

Verify the Signed Result (Backend)

Send signedToken to your backend and verify it with VeryAI's JWKS endpoint as described in the Native SDK integration guide. The Native SDK does not use OAuth authorization-code exchange.

Store userId after enrollment and pass it back for future verification. Treat userStatus: "pending" as a successful submission awaiting review; use webhooks for the later approved or rejected transition. A review that has already landed on rejected by the time the flow ends comes back as a failure instead — isSuccess: false, error: "5010", userStatus: "rejected" — with userId and signedToken still set.

Configuration Reference

VeryConfig

| Parameter | Type | Default | Description | | ------------------- | ------- | -------------- | ------------------------------------------------------------------ | | sdkKey | String | required | Your SDK API key | | userId | String? | undefined | Undefined for enrollment, user ID for verification | | language | String? | device | Locale code (e.g. "en", "es", "ja"). 38 languages supported. | | themeMode | String | "dark" | "dark" or "light" | | presentationStyle | String | "fullScreen" | "fullScreen" or "bottomSheet". "bottomSheet" is deprecated — it maps to the iOS page sheet / Android bottom sheet, both of which will be removed in a future major. | | livenessMode | String? | "touch" | Deprecated — ignored. The SDK picks the mode per device: the connect-the-dots touch points, except on constrained Android setups (3 GB of RAM or less, or a 32-bit process), which get the hand-gesture prompts. Still accepted so existing apps keep type-checking. | | debugLogging | boolean | false | Verbose API request/response logging to the native console. | | clientReferenceId | String? | undefined | Your session or transaction ID, included in related review webhook events. Server-enforced 255-character limit — a longer value fails the session, the SDK does not truncate. | | customStrings | object? | undefined | Overrides for the scan status copy, keyed by VeryCustomString. See Custom strings. |

Custom strings

The scan page's status copy can be replaced per call. A non-blank value wins over the SDK's built-in localized string; blank values and unrecognized keys are ignored and fall back to it.

import { VerySDK, VeryCustomString } from "@veryai/react-native-sdk";

await VerySDK.authenticate({
  sdkKey: "your_sdk_key",
  customStrings: {
    [VeryCustomString.SHOW_YOUR_HAND]: "Hold up your palm",
    [VeryCustomString.CONNECT_DOTS]: "Trace the dots",
  },
});

| Key | Default text | Where it shows | | --- | ------------ | -------------- | | VeryCustomString.SHOW_YOUR_HAND | Show your hand | Default scan-page status | | VeryCustomString.SHOW_YOUR_FIRST_HAND | Show your first hand | Scan-page status during first-time enrollment | | VeryCustomString.CONNECT_DOTS | Connect the dots | Connect-the-dots gesture prompt |

The SDK renders your value verbatim, so pass text you have already localized — language does not translate it. Plain strings work too; the constants exist so a typo becomes a compile error rather than a silently ignored key.

Liveness-only flow not wrapped yet. The native SDKs also ship a standalone liveness check (VeryAILiveness / VeryLivenessConfig) with showError / showSuccess options. The React Native wrapper currently exposes only the authenticate (palm-auth) flow; surfacing the liveness flow is tracked separately.

VeryResult

| Property | Type | Description | | -------------- | ------- | ------------------------------------------------------------- | | isSuccess | boolean | Whether authentication completed successfully | | code | string | SDK result code — "success" on completion. Not an OAuth authorization code and not meant for backend exchange; verify signedToken instead. | | userId | string | The user's VeryAI ID | | signedToken | string? | Signed JWT token (when available) | | userStatus | string? | approved, pending, rejected, restricted, or unknown. A status this wrapper version does not know is reported as unknown. | | error | string? | Error code string | | errorMessage | string? | Human-readable error message |

Requirements

  • React Native 0.73+ (declared in peerDependencies, so npm warns rather than failing at build time)
  • iOS 13.0+ / Android 6 (API 23)+
  • Physical device (no simulator)
  • Camera permission

Architecture

Both React Native architectures are supported — the package ships a TurboModule for the New Architecture and a legacy bridge module for the old one, and picks per build.

Note that the choice is no longer yours on recent React Native: 0.82 removed the option to disable the New Architecture (newArchEnabled: false is ignored), and 0.83 deleted the legacy architecture outright. The legacy path in this package therefore only matters if you are on React Native below 0.82.

Verified combinations

CI builds these two on every change to the SDK or the examples:

| Example | React Native | Architecture | | ------- | ------------ | ------------ | | examples/ReactNativeExample | 0.73.11 | legacy | | examples/ExpoNewArchExample (Expo SDK 54) | 0.81.5 | new |

Anything outside those two points is expected to work but is not covered by a build. If you hit a problem on a version we do not test, please report it with your React Native version.

Error Codes

The full list lives in the top-level README. One slim-mode-specific code worth calling out:

| Code | Name | Meaning | |------|-------------------------------|------------------------------------------------------------------------| | 6106 | NATIVE_LIB_DOWNLOAD_FAILED | Slim-mode partner: the SDK couldn't fetch the palm asset from CDN. Check internet, CDN allowlist, or revert to bundled mode. |

Use VerySDK.isSupported() to check device compatibility at runtime before showing the verification UI.

Prefetching the palm asset (slim mode)

In slim mode the palm asset is downloaded from CDN on the first scan, which can add a 5–15s wait. Call VerySDK.prefetch() early — e.g. at app launch — to warm that download in the background so the first scan is instant. It's fire-and-forget, safe to call repeatedly, and a no-op in bundled mode or once the asset is cached. (isSupported() already triggers the same warm-up as a side effect, so an explicit prefetch() is only needed when you want to start the download without the support check.)

import { VerySDK } from "@veryai/react-native-sdk";

// e.g. in your app's startup
VerySDK.prefetch();