Expo SecureStore provides a way to encrypt and securely store key-value pairs locally on the device. It uses platform-native keychain services (iOS Keychain Services and Android Keystore) to ensure data is encrypted and protected with hardware-backed security features including biometric authentication support.
npx expo install expo-secure-storeexpoimport * as SecureStore from 'expo-secure-store';For individual imports:
import {
setItemAsync,
getItemAsync,
deleteItemAsync,
isAvailableAsync,
WHEN_UNLOCKED,
type SecureStoreOptions
} from 'expo-secure-store';import * as SecureStore from 'expo-secure-store';
// Store a value
await SecureStore.setItemAsync('userToken', 'abc123');
// Retrieve a value
const token = await SecureStore.getItemAsync('userToken');
console.log(token); // 'abc123'
// Delete a value
await SecureStore.deleteItemAsync('userToken');
// Check if SecureStore is available
const isAvailable = await SecureStore.isAvailableAsync();import * as SecureStore from 'expo-secure-store';
// Store with biometric authentication requirement
await SecureStore.setItemAsync('sensitiveData', 'secret123', {
requireAuthentication: true,
authenticationPrompt: 'Please authenticate to access your data',
keychainAccessible: SecureStore.WHEN_UNLOCKED
});
// Retrieve with authentication
const data = await SecureStore.getItemAsync('sensitiveData', {
requireAuthentication: true,
authenticationPrompt: 'Authenticate to view your data'
});Asynchronous functions for storing, retrieving, and deleting encrypted key-value pairs.
/**
* Stores a key–value pair securely
* @param key The key to associate with the stored value. Keys may contain alphanumeric characters, `.`, `-`, and `_`
* @param value The value to store. Size limit is 2048 bytes
* @param options Configuration options for the storage operation
* @returns Promise that rejects if value cannot be stored on the device
*/
function setItemAsync(
key: string,
value: string,
options?: SecureStoreOptions
): Promise<void>;
/**
* Reads the stored value associated with the provided key
* @param key The key that was used to store the associated value
* @param options Configuration options for the retrieval operation
* @returns Promise that resolves to the previously stored value, or null if no entry exists or key has been invalidated
*/
function getItemAsync(
key: string,
options?: SecureStoreOptions
): Promise<string | null>;
/**
* Delete the value associated with the provided key
* @param key The key that was used to store the associated value
* @param options Configuration options for the deletion operation
* @returns Promise that rejects if the value can't be deleted
*/
function deleteItemAsync(
key: string,
options?: SecureStoreOptions
): Promise<void>;Synchronous functions that block the JavaScript thread during execution.
/**
* Stores a key–value pair synchronously
* Note: This function blocks the JavaScript thread, so the application may not be interactive when the requireAuthentication option is set to true until the user authenticates
* @param key The key to associate with the stored value. Keys may contain alphanumeric characters, `.`, `-`, and `_`
* @param value The value to store. Size limit is 2048 bytes
* @param options Configuration options for the storage operation
*/
function setItem(
key: string,
value: string,
options?: SecureStoreOptions
): void;
/**
* Synchronously reads the stored value associated with the provided key
* Note: This function blocks the JavaScript thread, so the application may not be interactive when reading a value with requireAuthentication option set to true until the user authenticates
* @param key The key that was used to store the associated value
* @param options Configuration options for the retrieval operation
* @returns Previously stored value, or null if no entry exists or key has been invalidated
*/
function getItem(
key: string,
options?: SecureStoreOptions
): string | null;Functions to check device capabilities and authentication support.
/**
* Returns whether the SecureStore API is enabled on the current device
* This does not check the app permissions
* @returns Promise which fulfils with a boolean, indicating whether the SecureStore API is available on the current device. Currently, this resolves true on Android and iOS only
*/
function isAvailableAsync(): Promise<boolean>;
/**
* Checks if the value can be saved with requireAuthentication option enabled
* @returns true if the device supports biometric authentication and the enrolled method is sufficiently secure. Otherwise, returns false. Always returns false on tvOS
* @platform android
* @platform ios
*/
function canUseBiometricAuthentication(): boolean;Options interface for configuring SecureStore operations.
interface SecureStoreOptions {
/**
* Android: Equivalent of the public/private key pair Alias
* iOS: The item's service, equivalent to kSecAttrService
* If the item is set with the keychainService option, it will be required to later fetch the value
*/
keychainService?: string;
/**
* Option responsible for enabling the usage of the user authentication methods available on the device while accessing data stored in SecureStore
* Android: Equivalent to setUserAuthenticationRequired(true) (requires API 23)
* iOS: Equivalent to biometryCurrentSet
* Complete functionality is unlocked only with a freshly generated key - this would not work in tandem with the keychainService value used for the others non-authenticated operations
*
* This option works slightly differently across platforms: On Android, user authentication is required for all operations.
* On iOS, the user is prompted to authenticate only when reading or updating an existing value (not when creating a new one).
*
* Warning: This option is not supported in Expo Go when biometric authentication is available due to a missing NSFaceIDUsageDescription.
* In release builds or when using continuous native generation, make sure to use the expo-secure-store config plugin.
*/
requireAuthentication?: boolean;
/**
* Custom message displayed to the user while requireAuthentication option is turned on
*/
authenticationPrompt?: string;
/**
* Specifies when the stored entry is accessible, using iOS's kSecAttrAccessible property
* @see Apple's documentation on keychain item accessibility
* @default SecureStore.WHEN_UNLOCKED
* @platform ios
*/
keychainAccessible?: KeychainAccessibilityConstant;
/**
* Specifies the access group the stored entry belongs to
* @see Apple's documentation on Sharing access to keychain items among a collection of apps
* @platform ios
*/
accessGroup?: string;
}Constants defining when stored data can be accessed on iOS.
type KeychainAccessibilityConstant = number;
/**
* The data in the keychain item cannot be accessed after a restart until the device has been unlocked once by the user
* This may be useful if you need to access the item when the phone is locked
*/
const AFTER_FIRST_UNLOCK: KeychainAccessibilityConstant;
/**
* Similar to AFTER_FIRST_UNLOCK, except the entry is not migrated to a new device when restoring from a backup
*/
const AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY: KeychainAccessibilityConstant;
/**
* The data in the keychain item can always be accessed regardless of whether the device is locked
* This is the least secure option
* @deprecated Use an accessibility level that provides some user protection, such as AFTER_FIRST_UNLOCK
*/
const ALWAYS: KeychainAccessibilityConstant;
/**
* Similar to WHEN_UNLOCKED_THIS_DEVICE_ONLY, except the user must have set a passcode in order to store an entry
* If the user removes their passcode, the entry will be deleted
*/
const WHEN_PASSCODE_SET_THIS_DEVICE_ONLY: KeychainAccessibilityConstant;
/**
* Similar to ALWAYS, except the entry is not migrated to a new device when restoring from a backup
* @deprecated Use an accessibility level that provides some user protection, such as AFTER_FIRST_UNLOCK_THIS_DEVICE_ONLY
*/
const ALWAYS_THIS_DEVICE_ONLY: KeychainAccessibilityConstant;
/**
* The data in the keychain item can be accessed only while the device is unlocked by the user
*/
const WHEN_UNLOCKED: KeychainAccessibilityConstant;
/**
* Similar to WHEN_UNLOCKED, except the entry is not migrated to a new device when restoring from a backup
*/
const WHEN_UNLOCKED_THIS_DEVICE_ONLY: KeychainAccessibilityConstant;false., -, and _requireAuthentication: trueThe SecureStore API may throw errors in the following scenarios: