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

react-native-easy-biometrics

v3.0.1

Published

Easy-to-use biometric authentication for React Native — Face ID, Touch ID, Fingerprint with typed errors, crypto keys, AbortSignal cancel, React Hook, and Expo support. New Architecture (TurboModules) ready.

Downloads

1,501

Readme

React Native Easy Biometrics


✨ Features

| Feature | iOS | Android | | --------------------------------------------------------- | :-: | :-----: | | Biometry type detection (FaceID/TouchID/Fingerprint/Iris) | ✅ | ✅ | | Enrollment check | ✅ | ✅ | | Biometric authentication with options | ✅ | ✅ | | Prompt subtitle | — | ✅ | | Typed error codes (10 error types) | ✅ | ✅ | | Cancel via AbortSignal | ✅ | ✅ | | Security level detection (None/Secret/Weak/Strong) | ✅ | ✅ | | EC256 keys (Secure Enclave / StrongBox) | ✅ | ✅ | | RSA 2048 key pair generation | ✅ | ✅ | | Multiple key aliases | ✅ | ✅ | | Biometric-protected payload signing | ✅ | ✅ | | Encrypted biometric storage 🆕 | ✅ | ✅ | | Biometric change detection | ✅ | ✅ | | Biometric change event listener | ✅ | ✅ | | Device integrity (root/jailbreak detection) | ✅ | ✅ | | Screen capture protection 🆕 | ✅ | ✅ | | Device diagnostics 🆕 | ✅ | ✅ | | Device credential fallback control | ✅ | ✅ | | useBiometrics() React Hook | ✅ | ✅ | | useBiometricGuard() Hook 🆕 | ✅ | ✅ | | Expo Config Plugin | ✅ | ✅ | | New Architecture (TurboModules) | ✅ | ✅ | | GitHub Actions CI 🆕 | ✅ | ✅ |

📦 Installation

npm install react-native-easy-biometrics
# or
yarn add react-native-easy-biometrics

iOS

cd ios && pod install

Add this to your Info.plist (or use the Expo plugin to do it automatically):

<key>NSFaceIDUsageDescription</key>
<string>Allow the app to use Face ID for authentication</string>

Android

Add the biometric permission to your AndroidManifest.xml:

<uses-permission android:name="android.permission.USE_BIOMETRIC" />

Note: Requires minSdkVersion 23 (Android 6.0+). The library auto-links on React Native 0.60+ — no manual linking needed.

ProGuard/R8: Rules are applied automatically via consumer-rules.pro — no manual setup needed even with minifyEnabled true.

Expo

Add the plugin to your app.json:

{
  "expo": {
    "plugins": [
      [
        "react-native-easy-biometrics",
        {
          "faceIDPermission": "Allow $(PRODUCT_NAME) to use Face ID for secure login"
        }
      ]
    ]
  }
}

Then run:

npx expo prebuild

🚀 Quick Start

Using the React Hook (recommended)

import { useBiometrics, BiometryType } from 'react-native-easy-biometrics';

function LoginScreen() {
  const { available, biometryType, authenticate, isAuthenticating } =
    useBiometrics();

  const handleLogin = async () => {
    const result = await authenticate({
      promptMessage: 'Verify your identity to continue',
    });

    if (result.success) {
      // Navigate to home
    } else {
      console.log('Auth failed:', result.error, result.message);
    }
  };

  if (!available) return <Text>Biometrics not available</Text>;

  return (
    <Button
      title={`Login with ${biometryType}`}
      onPress={handleLogin}
      disabled={isAuthenticating}
    />
  );
}

Using the API directly

import RNBiometrics, {
  BiometryType,
  BiometricError,
} from 'react-native-easy-biometrics';

// 1. Check what's available
const sensor = await RNBiometrics.getBiometryType();
console.log(sensor.biometryType); // 'FaceID' | 'TouchID' | 'Fingerprint' | 'Iris' | 'None'
console.log(sensor.biometryTypes); // e.g. ['Fingerprint', 'FaceID'] on Samsung

// 2. Check if enrolled
const enrolled = await RNBiometrics.isEnrolled();

// 3. Authenticate — only promptMessage is required!
const result = await RNBiometrics.authenticate({
  promptMessage: 'Verify your identity to continue',
});

// Or with all options:
const result2 = await RNBiometrics.authenticate({
  promptMessage: 'Verify your identity to continue',
  promptTitle: 'Confirm Payment', // default: 'Authentication'
  promptSubtitle: '$99.99 — Apple Store', // Android only, ignored on iOS
  cancelButtonText: 'Use Password', // Android only, default: 'Cancel'
  fallbackLabel: 'Enter Passcode', // iOS only
  disableDeviceFallback: false, // default: false
});

if (result.success) {
  console.log('Authenticated!');
} else {
  switch (result.error) {
    case BiometricError.USER_CANCEL:
      console.log('User cancelled');
      break;
    case BiometricError.LOCKOUT:
      console.log('Too many attempts');
      break;
    case BiometricError.NOT_ENROLLED:
      console.log('No biometrics enrolled');
      break;
  }
}

Cancelling authentication

const controller = new AbortController();

// Start auth
RNBiometrics.authenticate({
  promptMessage: 'Verify identity',
  signal: controller.signal,
});

// Cancel after 5 seconds
setTimeout(() => controller.abort(), 5000);

⚡ Quick Status Check

Get everything you need in a single call:

const status = await RNBiometrics.getStatus();
// {
//   available: true,
//   biometryType: 'Fingerprint',
//   biometryTypes: ['Fingerprint', 'FaceID'],
//   enrolled: true,
//   securityLevel: 3, // BIOMETRIC_STRONG
//   error?: string
// }

if (status.available && status.enrolled) {
  console.log(`Ready: ${status.biometryType}`);
}

🔐 Crypto Key Management

Generate RSA 2048 key pairs protected by biometric authentication. Perfect for banking apps, secure login, and payload signing.

import RNBiometrics from 'react-native-easy-biometrics';

// Generate a key pair (private key stored in Keychain/Keystore)
const { publicKey } = await RNBiometrics.createKeys();
console.log('Public key:', publicKey); // Send to your server

// Sign a payload (user will be prompted for biometrics)
const result = await RNBiometrics.createSignature({
  payload: 'transaction-id-12345',
  promptMessage: 'Sign this transaction',
});

if (result.success) {
  // Send result.signature to your server for verification
  await verifyOnServer(result.signature, publicKey);
}

// Check if keys exist
const exists = await RNBiometrics.biometricKeysExist();

// Delete keys
await RNBiometrics.deleteKeys();

Multiple Key Aliases

Use different key pairs for different purposes (e.g. login vs payments):

// Create separate key pairs for different use cases
const loginKey = await RNBiometrics.createKeys('login');
const paymentKey = await RNBiometrics.createKeys('payment');

// Sign with a specific key
const result = await RNBiometrics.createSignature({
  payload: 'payment:99.99:USD',
  promptMessage: 'Confirm payment',
  keyAlias: 'payment',
});

// Check/delete specific keys
await RNBiometrics.biometricKeysExist('payment'); // true
await RNBiometrics.deleteKeys('payment');
await RNBiometrics.biometricKeysExist('payment'); // false
await RNBiometrics.biometricKeysExist('login'); // still true

Note: If you don't pass a keyAlias, all crypto methods default to 'default'.

� Biometric Change Detection

Detect if biometrics have been added or removed since the last check. Useful for re-prompting authentication after a security change.

import RNBiometrics from 'react-native-easy-biometrics';

// 1. Get and save the current biometric state hash
const hash = await RNBiometrics.getBiometricStateHash();
// Save hash to AsyncStorage or your backend

// 2. Later, check if biometrics have changed
const changed = await RNBiometrics.isBiometricChanged(savedHash);
if (changed) {
  // A fingerprint/face was added or removed!
  // Re-authenticate the user or invalidate tokens
}

| Platform | How it works | | ----------- | -------------------------------------------------------------------------------------------------------------------------- | | iOS | Uses evaluatedPolicyDomainState — a system-provided hash that changes when biometric enrollment changes | | Android | Keys created with setInvalidatedByBiometricEnrollment(true) — the key becomes permanently invalid when biometrics change |

�🔒 Security Level

Detect the security level to implement tiered access:

import RNBiometrics, { SecurityLevel } from 'react-native-easy-biometrics';

const level = await RNBiometrics.getSecurityLevel();

switch (level) {
  case SecurityLevel.BIOMETRIC_STRONG:
    // Allow high-value operations (e.g. $10,000 transfers)
    break;
  case SecurityLevel.BIOMETRIC_WEAK:
    // Allow medium-value operations (e.g. $100 transfers)
    break;
  case SecurityLevel.SECRET:
    // Only PIN/passcode available
    break;
  case SecurityLevel.NONE:
    // No security enrolled
    break;
}

📖 API Reference

Methods

| Method | Returns | Description | | ------------------------------- | -------------------------------- | -------------------------------------------- | | canAuthenticate() | Promise<boolean> | Check if biometric auth is available | | getBiometryType() | Promise<SensorResult> | Detect biometric sensor type(s) | | isEnrolled() | Promise<boolean> | Check if biometrics are enrolled | | getSecurityLevel() | Promise<SecurityLevel> | Get device security level | | getStatus() | Promise<BiometricStatus> | Everything in one call ⭐ | | authenticate(options) | Promise<AuthResult> | Authenticate with typed results | | createKeys(alias?, keyType?) | Promise<CreateKeysResult> | Generate EC256 or RSA2048 key pair | | createSignature(options) | Promise<CreateSignatureResult> | Sign payload (auto-detects EC/RSA) | | biometricKeysExist(keyAlias?) | Promise<boolean> | Check if keys exist for alias | | deleteKeys(keyAlias?) | Promise<boolean> | Delete stored keys for alias | | getBiometricStateHash() | Promise<string \| null> | Get current biometric enrollment hash | | isBiometricChanged(savedHash) | Promise<boolean> | Check if biometrics changed since saved hash | | getDeviceIntegrity() | Promise<DeviceIntegrityResult> | Root/jailbreak detection + risk level | | onBiometricChange(callback) | () => void | Subscribe to enrollment changes | | secureStore(key, value, msg?) | Promise<boolean> | Store value with biometric encryption | | secureGet(key, msg?) | Promise<string \| null> | Get biometric-protected value | | secureDelete(key) | Promise<boolean> | Delete a stored value | | secureGetAllKeys() | Promise<string[]> | List all secure storage keys | | setScreenCaptureProtection(b) | Promise<boolean> | Prevent screenshots/recording | | getDiagnosticInfo() | Promise<DiagnosticInfo> | Device + biometric capabilities |

AuthOptions

| Option | Type | Required | Platform | Description | | ----------------------- | ------------- | -------- | -------- | ------------------------------------------------- | | promptMessage | string | ✅ | Both | Message displayed on the prompt | | promptTitle | string | — | Both | Title of the prompt. Default: 'Authentication' | | promptSubtitle | string | — | Android | Subtitle below the title. Ignored on iOS. | | cancelButtonText | string | — | Android | Cancel button text. Default: 'Cancel' | | fallbackLabel | string | — | iOS | Fallback button text (e.g. "Enter Passcode") | | disableDeviceFallback | boolean | — | Both | Biometric only, no PIN fallback. Default: false | | signal | AbortSignal | — | Both | Cancel the prompt programmatically |

Hook

| Property | Type | Description | | ------------------ | ---------------------------------- | ----------------------------- | | available | boolean | Biometric hardware available | | biometryType | BiometryType | Primary biometric sensor type | | biometryTypes | BiometryType[] | All supported biometric types | | isEnrolled | boolean | Biometric data enrolled | | securityLevel | SecurityLevel | Device security level | | isAuthenticating | boolean | Auth in progress | | loading | boolean | Initial state loading | | authenticate | (options) => Promise<AuthResult> | Authenticate function | | cancel | () => void | Cancel authentication |

Enums

BiometryType: FaceID | TouchID | Fingerprint | Iris | None

KeyType: EC256 (Secure Enclave) | RSA2048 (default)

BiometricError: user_cancel | lockout | not_enrolled | not_available | system_cancel | passcode_not_set | authentication_failed | app_cancel | lockout_permanent | unknown

SecurityLevel: NONE (0) | SECRET (1) | BIOMETRIC_WEAK (2) | BIOMETRIC_STRONG (3)

RiskLevel: NONE | LOW | MEDIUM | HIGH

Hooks

| Hook | Description | | ------------------------- | ---------------------------------------------- | | useBiometrics() | Complete biometrics interface with auto-status | | useBiometricGuard(opts) | Screen-level auth protection |

🤝 Contributing

See CONTRIBUTING.md for setup and guidelines.

🔄 Migrating from react-native-biometrics

Coming from react-native-biometrics (SelfLender) or @sbaiahmed1/react-native-biometrics? See the full Migration Guide with API mapping and code examples.

📝 Changelog

See CHANGELOG.md for the full version history.

License

MIT