Skip to main content
Glama
securestore.md5.18 kB
--- title: SecureStore description: A library that provides a way to encrypt and securely store key-value pairs locally on the device. sourceCodeUrl: https://github.com/expo/expo/tree/sdk-51/packages/expo-secure-store packageName: expo-secure-store iconUrl: /static/images/packages/expo-secure-store.png platforms: ["android", "ios"] --- import { ConfigPluginExample, ConfigReactNative, ConfigPluginProperties, } from '~/ui/components/ConfigSection'; `expo-secure-store` provides a way to encrypt and securely store key–value pairs locally on the device. Each Expo project has a separate storage system and has no access to the storage of other Expo projects. **Size limit for a value is 2048 bytes. An attempt to store larger values may fail. Currently, we print a warning when the limit is reached, however, in a future SDK version an error might be thrown.** **The `requireAuthentication` option is not supported in Expo Go when biometric authentication is available due to a missing `NSFaceIDUsageDescription` key.** > This API is not compatible with devices running Android 5 or lower. ## Installation ## Configuration in app config You can configure `expo-secure-store` using its built-in [config plugin](/config-plugins/introduction/) if you use config plugins in your project ([EAS Build](/build/introduction) or `npx expo run:[android|ios]`). The plugin allows you to configure various properties that cannot be set at runtime and require building a new app binary to take effect. ```json app.json { "expo": { "plugins": [ [ "expo-secure-store", { "faceIDPermission": "Allow $(PRODUCT_NAME) to access your Face ID biometric data." } ] ] } } ``` Add `NSFaceIDUsageDescription` key to **Info.plist**: ```xml Info.plist <key>NSFaceIDUsageDescription</key> <string>Allow $(PRODUCT_NAME) to access your Face ID biometric data.</string> ``` ## Platform value storage ### Android On Android, values are stored in [`SharedPreferences`](https://developer.android.com/training/data-storage/shared-preferences), encrypted with [Android's Keystore system](https://developer.android.com/training/articles/keystore.html). ### iOS > For iOS standalone apps, data stored with `expo-secure-store` can persist across app installs. On iOS, values are stored using the [keychain services](https://developer.apple.com/documentation/security/keychain_services) as `kSecClassGenericPassword`. iOS has the additional option of being able to set the value's `kSecAttrAccessible` attribute, which controls when the value is available to be fetched. #### Exempting encryption prompt Apple App Store Connect prompts you to select the type of encryption algorithm your app implements. This is known as **Export Compliance Information**. It is asked when publishing the app or submitting for TestFlight. When using `expo-secure-store`, you can set the [`ios.config.usesNonExemptEncryption`](../config/app/#usesnonexemptencryption) property to `false` in the app config: {/* prettier-ignore */} ```json app.json { "expo": { "ios": { "config": { "usesNonExemptEncryption": false } /* @hide ... */ /* @end */ } } } ``` Setting this property automatically handles the compliance information prompt. ## Usage ```jsx async function save(key, value) { await SecureStore.setItemAsync(key, value); } async function getValueFor(key) { let result = await SecureStore.getItemAsync(key); if (result) { alert("🔐 Here's your value 🔐 \n" + result); } else { alert('No values stored under that key.'); } } const [key, onChangeKey] = useState('Your key here'); const [value, onChangeValue] = useState('Your value here'); return ( <View style={styles.container}> <Text style={styles.paragraph}>Save an item, and grab it later!</Text> {/* @hide Add some TextInput components... */} <TextInput style={styles.textInput} clearTextOnFocus onChangeText={text => onChangeKey(text)} value={key} /> <TextInput style={styles.textInput} clearTextOnFocus onChangeText={text => onChangeValue(text)} value={value} /> {/* @end */} <Button title="Save this key/value pair" onPress={() => { save(key, value); onChangeKey('Your key here'); onChangeValue('Your value here'); }} /> <Text style={styles.paragraph}>🔐 Enter your key 🔐</Text> <TextInput style={styles.textInput} onSubmitEditing={event => { getValueFor(event.nativeEvent.text); }} placeholder="Enter the key for the value you want to get" /> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', paddingTop: 10, backgroundColor: '#ecf0f1', padding: 8, }, paragraph: { marginTop: 34, margin: 24, fontSize: 18, fontWeight: 'bold', textAlign: 'center', }, textInput: { height: 35, borderColor: 'gray', borderWidth: 0.5, padding: 4, }, }); ``` ## API ```js ```

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jaksm/expo-docs-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server