Expoexpo-secure-storeSecurityAuthentication

Securely Store Tokens in Expo (expo-secure-store Guide)

Store auth tokens and secrets safely in Expo with expo-secure-store — encrypted storage backed by the iOS Keychain and Android Keystore. Learn set/get/delete, options, limits, and an auth pattern. SDK 54+.

DeveloperMill2 min read

Storing an auth token in plain AsyncStorage is a common security mistake — anyone with device access or a backup can read it. expo-secure-store encrypts small secrets using the iOS Keychain and Android Keystore, which is why it's the most-searched module for handling tokens in Expo. Here's how to use it.

Install

npx expo install expo-secure-store

Set, get, and delete a secret

The whole API is three async functions:

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

// Save
await SecureStore.setItemAsync("session_token", "eyJhbGciOi...")

// Read (returns null if missing)
const token = await SecureStore.getItemAsync("session_token")

// Remove (e.g. on logout)
await SecureStore.deleteItemAsync("session_token")

Require device authentication

Gate a secret behind Face ID / Touch ID / device passcode:

await SecureStore.setItemAsync("private_key", value, {
  requireAuthentication: true,
  keychainAccessible: SecureStore.WHEN_UNLOCKED,
})

Now reading private_key prompts for biometrics before it resolves.

A practical auth pattern

Wrap SecureStore in a tiny session helper you can reuse across your app:

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

const KEY = "session_token"

export const session = {
  save: (token: string) => SecureStore.setItemAsync(KEY, token),
  get: () => SecureStore.getItemAsync(KEY),
  clear: () => SecureStore.deleteItemAsync(KEY),
}

On app launch, call session.get() to decide whether to show the app or the sign-in screen. This pairs directly with the Expo authentication guide.

Gotchas

  • Small values only — roughly a 2KB limit per entry. Keep large data in expo-file-system or expo-sqlite.
  • No web support — guard platform-specific code, or use a web fallback for universal apps.
  • Keys must be alphanumeric (plus ., -, _).
  • Deleting the app clears the store, so don't treat it as permanent server-side state.

Next steps

SecureStore is the storage half of auth — read the full how to add authentication to an Expo app guide next, and see where it fits among the top 10 Expo SDK modules.

Frequently asked questions

What is expo-secure-store used for?

expo-secure-store encrypts and stores small key/value secrets — like auth tokens, API keys, and refresh tokens — using the iOS Keychain and Android Keystore. It's the secure alternative to AsyncStorage, which stores data in plain text.

Is there a size limit for expo-secure-store?

Yes. It's designed for small values (tokens and keys), with a practical limit around 2KB per entry on Android. Store large data in expo-file-system or expo-sqlite and keep only secrets in SecureStore.

Does expo-secure-store work on the web?

No. SecureStore relies on native secure storage that browsers don't provide, so it's unavailable on web. For universal apps, fall back to another storage mechanism on web and use SecureStore on native.

Build it faster with a template

Production-ready Expo React Native templates with the patterns from this post already wired up.

Browse templates