CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-expo-secure-store

Provides a way to encrypt and securely store key-value pairs locally on the device.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

Expo SecureStore

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.

Package Information

  • Package Name: expo-secure-store
  • Package Type: npm
  • Language: TypeScript
  • Installation: npx expo install expo-secure-store
  • Peer Dependencies: expo

Core Imports

import * as SecureStore from 'expo-secure-store';

For individual imports:

import { 
  setItemAsync, 
  getItemAsync, 
  deleteItemAsync, 
  isAvailableAsync,
  WHEN_UNLOCKED,
  type SecureStoreOptions 
} from 'expo-secure-store';

Basic Usage

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();

Advanced Usage with Authentication

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'
});

Capabilities

Storage Operations

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 Operations

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;

Availability and Authentication

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;

Configuration Options

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;
}

Keychain Accessibility Constants

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;

Platform Support

  • iOS: Full support via iOS Keychain Services
  • Android: Full support via Android Keystore (API 23+ required for biometric authentication features)
  • tvOS: Basic keychain operations supported, but biometric authentication always returns false
  • Web: Not supported (operations will fail on web platforms)

Key Limitations and Considerations

Value Size Limit

  • Maximum value size: 2048 bytes
  • Values exceeding this limit will generate a warning but may still be stored (behavior may change in future versions)

Key Requirements

  • Keys must contain only alphanumeric characters, ., -, and _
  • Keys cannot be empty strings

Authentication Behavior

  • iOS: User authentication is required only when reading or updating existing values (not when creating new ones)
  • Android: User authentication is required for all operations when requireAuthentication: true
  • Keys are automatically invalidated when biometric data changes (e.g., adding new fingerprints)

Expo Go Limitations

  • Biometric authentication is not supported in Expo Go due to missing NSFaceIDUsageDescription
  • Use development builds or production builds for full authentication functionality

Error Handling

The SecureStore API may throw errors in the following scenarios:

  • Invalid key format: Keys containing invalid characters or empty strings
  • Invalid value type: Non-string values passed to storage functions
  • Storage failures: Device-specific errors when storing, retrieving, or deleting values
  • Authentication failures: When user cancels authentication or biometric authentication fails
  • Platform limitations: When attempting to use SecureStore on unsupported platforms (web)

Security Features

  • Hardware-backed encryption: Uses iOS Keychain Services and Android Keystore for secure storage
  • Biometric authentication: Optional user authentication via Touch ID, Face ID, or fingerprint
  • Access control: Configurable accessibility levels controlling when data can be accessed
  • App group sharing: Support for sharing keychain items between related apps (iOS)
  • Device-specific storage: Options to prevent data migration during device backup/restore
  • Automatic key invalidation: Keys become inaccessible when biometric enrollment changes
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/expo-secure-store@15.0.x
Publish Source
CLI
Badge
tessl/npm-expo-secure-store badge