AlgoInsight

Q&A

How to store sensitive data in a React Native app

By AlgoInsight Team2026-06-07androidfrontendiosmobilereactjavascript

Overview

Mobile apps often need to persist secrets: auth tokens, refresh tokens, API keys, biometric flags. The wrong place - AsyncStorage, Redux persistence, or hard-coded constants - leaves them readable by anyone with device or bundle access. The right place is the OS-provided secure store, which encrypts data and is backed by device hardware (Secure Enclave / TEE).

graph TD
    A[Sensitive data?] --> B[❌ AsyncStorage: plain text]
    A --> C[❌ Hard-coded in bundle: reverse-engineerable]
    A --> D[✓ Secure storage]
    D --> D1[iOS Keychain]
    D --> D2[Android Keystore / EncryptedSharedPreferences]
    D --> E[Via react-native-keychain / expo-secure-store]
    style D fill:#1e1b4b,color:#fff

Why Not AsyncStorage?

AsyncStorage is unencrypted key-value storage - data sits in plain text in the app's sandbox, readable on rooted/jailbroken devices, in backups, or via debugging tools. It's fine for non-sensitive preferences (theme, last tab) but never for secrets.

Option 1: react-native-keychain (bare RN)

Wraps iOS Keychain and Android Keystore with a simple API:

import * as Keychain from "react-native-keychain";

// store
await Keychain.setGenericPassword("authToken", token, {
  accessible: Keychain.ACCESSIBLE.WHEN_UNLOCKED,   // only when device unlocked
});

// retrieve
const creds = await Keychain.getGenericPassword();
if (creds) { const token = creds.password; }

// remove
await Keychain.resetGenericPassword();

It can also require biometric authentication (Face ID / fingerprint) to unlock the stored value.

Option 2: expo-secure-store (Expo)

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

await SecureStore.setItemAsync("authToken", token);
const token = await SecureStore.getItemAsync("authToken");
await SecureStore.deleteItemAsync("authToken");

Backed by Keychain (iOS) and encrypted storage (Android) under the hood.

What "Hard-Coding Secrets" Gets Wrong

Putting an API key or secret directly in JS/.env bundled into the app does not hide it - the JavaScript bundle ships to the device and can be extracted and inspected. Client apps fundamentally can't keep an embedded secret secret. The right architecture:

Defense in Depth

Why This Matters in Interviews

This is a mobile security question testing judgment. The essentials: use platform secure storage (Keychain/Keystore) via react-native-keychain or expo-secure-store; never use AsyncStorage for secrets (it's plain text); and understand that embedding a secret in the app can't truly hide it - real secrets belong on a server, while the device holds only revocable, short-lived tokens. Mentioning biometric gating, HTTPS, and token rotation rounds out a strong answer.

Common Pitfalls

References

More answers