Registry /
auth-security / expo-local-authentication
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslnode 18–226 runs
build_error
glibcnode 18–226 runs
build_error
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
LocalAuthentication
✓ import * as LocalAuthentication from 'expo-local-authentication';
✗ const LocalAuthentication = require('expo-local-authentication');
This is the standard ESM import for Expo modules, bringing all functions into the `LocalAuthentication` namespace. CommonJS `require()` is generally discouraged in modern Expo/React Native projects.
authenticateAsync
✓ await LocalAuthentication.authenticateAsync({ /* options */ });
The primary method to prompt the user for biometric authentication. Accessed as a method of the `LocalAuthentication` namespace.
hasHardwareAsync
✓ await LocalAuthentication.hasHardwareAsync();
Used to check if the device supports any form of biometric authentication. Should always be checked before attempting authentication.
This quickstart demonstrates the full biometric authentication flow, including checking for hardware availability and user enrollment before attempting to authenticate the user. It also provides basic error handling for common authentication outcomes.
import * as LocalAuthentication from 'expo-local-authentication';
import { Alert, Platform } from 'react-native'; // Assuming a React Native environment for Alert
async function performBiometricAuth() {
// 1. Check if biometric hardware is available
const hasHardware = await LocalAuthentication.hasHardwareAsync();
if (!hasHardware) {
Alert.alert('Authentication Error', 'Biometric hardware is not available on this device.');
return;
}
// 2. Check if biometrics are enrolled
const isEnrolled = await LocalAuthentication.isEnrolledAsync();
if (!isEnrolled) {
Alert.alert('Authentication Error', 'No biometrics (Face ID/Fingerprint) are enrolled. Please set them up in your device settings.');
return;
}
// 3. Attempt to authenticate
try {
const result = await LocalAuthentication.authenticateAsync({
promptMessage: 'Authenticate to access your account',
cancelLabel: 'Use Password', // Android specific (optional, customizes button text)
fallbackLabel: 'Enter Passcode', // iOS specific for older versions (optional)
disableDeviceFallback: false, // iOS specific (optional, disables passcode fallback)
});
if (result.success) {
Alert.alert('Success!', 'Biometric authentication successful!');
// Proceed with authenticated user flow
} else {
let errorMessage = 'Authentication failed.';
if (result.error === 'user_cancel') {
errorMessage = 'Authentication canceled by user.';
} else if (result.error === 'system_cancel') {
errorMessage = 'Authentication canceled by system (e.g., app in background).';
} else if (result.error === 'passcode_not_set') {
errorMessage = 'Device passcode not set, biometric authentication is not possible.';
} else if (result.error === 'not_enrolled') {
errorMessage = 'No biometrics enrolled on the device.';
} else if (result.error === 'not_available') {
errorMessage = 'Biometric hardware not available or supported.';
}
Alert.alert('Authentication Failed', `${errorMessage} (Error: ${result.error})`);
}
} catch (error) {
console.error('Biometric authentication unexpected error:', error);
Alert.alert('Error', 'An unexpected error occurred during authentication.');
}
}
// To integrate this in an Expo/React Native component:
// import React from 'react';
// import { Button, View } from 'react-native';
// const BiometricAuthScreen = () => (
// <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
// <Button title="Authenticate with Biometrics" onPress={performBiometricAuth} />
// </View>
// );
// export default BiometricAuthScreen;
// For immediate testing (e.g., in a standalone script or effect hook):
// (async () => {
// if (Platform.OS === 'web') {
// console.warn('Local authentication is not available on web.');
// return;
// }
// // await performBiometricAuth();
// })();
Errors
Common errors & fixes
This app has not been granted the necessary permissions for Face ID.
Missing `NSFaceIDUsageDescription` in `app.json`'s `infoPlist` for iOS.
fixAdd `"NSFaceIDUsageDescription": "Your app needs Face ID to authenticate you."` to `expo.ios.infoPlist` in your `app.json`.
Biometric authentication is not available on this device.
The device either lacks biometric hardware or the `expo-local-authentication` module cannot access it.
fixEnsure `LocalAuthentication.hasHardwareAsync()` returns `true` before proceeding. If it returns `false`, gracefully inform the user.
No biometrics enrolled on the device.
The device has biometric hardware, but the user has not set up Face ID or Fingerprint authentication in their device settings.
fixEnsure `LocalAuthentication.isEnrolledAsync()` returns `true` before attempting authentication. If it returns `false`, prompt the user to enroll biometrics in their device settings.
Audit
Dependencies
exporequiredRequired peer dependency for all Expo modules to function correctly within the Expo SDK environment.