mCodex/react-native-sensitive-info
mCodex/react-native-sensitive-info has 1,071 GitHub stars and 236 forks. GitHot measured +1 stars in 24 hours. Last checked 2026-11-09 10:43 UTC. Last push 2026-11-02.
🔐 React Native secure storage, rebuilt with Nitro Modules ⚡️ Biometric-ready, StrongBox-aware, and metadata-rich for modern mobile apps
Measured star growth
- in 24h
- +1
- in 7 days
- Collecting history
- in 15 days
- Collecting history
- in 1 month
- Collecting history
Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.
README.md
Originalreact-native-sensitive-info
Secure storage for React Native using iOS Keychain and Android Keystore. The resolved protection level depends on the device and requested access policy. The library exposes a Promise-based API and React hooks.
[!NOTE] Upgrading from v5? See MIGRATION.md. v6 requires the New Architecture (RN 0.76+) and
react-native-nitro-modules. Windows support was removed.
Table of contents
- 🧭 Platform support
- ⚙️ Installation
- ⚡️ Quick start
- ⚛️ React Hooks API
- 📚 API reference
- 🛡️ Security
- 🌳 Tree-shaking
- 🎮 Example app
- 🛠️ Development
- 🩺 Troubleshooting
- 🤝 Contributing
- 📄 License
🧭 Platform support
| Platform | Baseline / declaration | Notes |
|---|---|---|
| React Native | 0.88.1 | New Architecture and react-native-nitro-modules required; this is the current verified example baseline. |
| iOS | RN-defined | 15.1 with React Native 0.88.1. Add NSFaceIDUsageDescription when using Face ID. |
| Android | API 23 | Example targets API 24. StrongBox requires API 28+ and is used only when selected and available. |
| macOS, visionOS, watchOS | Declared by the podspec | Not covered by the current native build matrix; compatibility is unverified. |
⚙️ Installation
npm install react-native-sensitive-info react-native-nitro-modules
# yarn add react-native-sensitive-info react-native-nitro-modules
# pnpm add react-native-sensitive-info react-native-nitro-modules
No manual linking required — Nitro handles autolinking.
🍏 iOS
Run pod install, then add to Info.plist if you use biometric prompts:
<key>NSFaceIDUsageDescription</key>
<string>Face ID is used to authenticate access to secure data.</string>
🤖 Android
Add to AndroidManifest.xml:
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
🧪 Expo
[!WARNING] Expo Go does not include native Nitro modules. Use a custom dev client or an EAS build.
Add the plugin to app.json, then run npx expo prebuild --clean:
{
"expo": {
"plugins": ["react-native-sensitive-info"]
}
}
For a full Expo walkthrough see EXPO.md.
⚡️ Quick start
import { setItem, getItem, deleteItem } from 'react-native-sensitive-info'
// Write — uses the strongest available security policy by default
await setItem('session-token', 'abc123', { service: 'auth' })
// Read — returns value + metadata
const item = await getItem('session-token', { service: 'auth' })
const sessionToken = item?.value
if (sessionToken) {
restoreSession(sessionToken)
}
console.log(item?.metadata.securityLevel) // e.g. 'secureEnclave'
// Remove
await deleteItem('session-token', { service: 'auth' })
Building a component? The hooks API handles loading states, cleanup, and error boundaries.
⚛️ React Hooks API (Recommended)
import { Text, View, ActivityIndicator } from 'react-native'
import {
useSecureStorage,
useSecurityAvailability,
} from 'react-native-sensitive-info/hooks'
function SecretsView() {
const { items, isLoading, error, saveSecret, removeSecret } =
useSecureStorage({ service: 'myapp', includeValues: true })
const { data: capabilities } = useSecurityAvailability()
if (isLoading) return <ActivityIndicator />
if (error) return <Text>Error: {error.message}</Text>
return (
<View>
{items.map(item => (
<Text key={item.key}>
{item.key}: {item.value} ({item.metadata.securityLevel})
</Text>
))}
<Text>Biometry: {capabilities?.biometry ? 'available' : 'unavailable'}</Text>
</View>
)
}
| Hook | Use case |
|---|---|
useSecureStorage() |
List, add, and remove all secrets in a service. |
useSecret() |
Fetch a single secret with read/write mutations. |
useHasSecret() |
Lightweight existence check (no decryption). |
useSecurityAvailability() |
Query device capabilities (auto-cached). |
useKeyRotation() |
Rotate the master key for a service. |
useBiometryStatusWatcher() |
Subscribe to biometric enrollment-state transitions. |
All hooks auto-cancel in-flight requests on unmount. For advanced patterns and best practices see HOOKS.md.
📚 API reference
| Method | Description |
|---|---|
setItem(key, value, options?) |
Write a secret using the strongest available security policy. |
getItem(key, options?) |
Read a secret and its metadata. Pass includeValue: false to skip the payload. |
hasItem(key, options?) |
Check whether a secret exists (no biometric prompt). |
deleteItem(key, options?) |
Remove a secret. Returns true if something was deleted. |
getAllItems(options?) |
List all secrets in a service. |
clearService(options?) |
Remove every secret in a service namespace. |
getSupportedSecurityLevels() |
Snapshot of device capabilities (biometrics, Secure Enclave, StrongBox, …). |
canUseAccessControl(policy) |
Check whether a given access-control policy is supported on this device. |
rotateKeys(options?) |
Bump the active key version; subsequent reads transparently re-encrypt older entries. |
Common options:
| Option | Default | Description |
|---|---|---|
service |
bundle ID / 'default' |
Logical namespace for secrets. |
accessControl |
'secureEnclaveBiometry' |
Preferred write policy; native layer picks the strongest supported fallback. |
authenticationPrompt |
— | Localized strings for biometric / device-credential prompts. |
iosSynchronizable |
false |
Sync via iCloud Keychain. |
keychainGroup |
— | Custom Keychain access group. |
Errors are typed — import predicates from react-native-sensitive-info/errors:
import {
isAuthenticationCanceledError,
isKeyInvalidatedError,
isIntegrityViolationError,
} from 'react-native-sensitive-info/errors'
🛡️ Security
Android stores AES-GCM ciphertext and keeps its encryption keys in Android Keystore. iOS stores values in Keychain and applies the selected Keychain access policy. The protection level depends on the requested policy and device; check the returned securityLevel instead of assuming hardware-backed storage.
New entries also carry an HMAC-SHA256 integrity tag. Older entries without a tag remain readable for compatibility, and a valid old record can be replayed because the library has no separate trusted rollback counter. Integrity tags are not a guarantee against rollback or a compromised app process.
For the storage model and its limits, see THREAT_MODEL.md.
🌳 Tree-shaking
All entry points are side-effect-free ("sideEffects": false). Import only what you use:
| Subpath | Contents |
|---|---|
react-native-sensitive-info |
Core API (setItem, getItem, hasItem, deleteItem, getAllItems, clearService, rotateKeys, …) |
react-native-sensitive-info/hooks |
React hooks (useSecureStorage, useSecret, useKeyRotation, …) |
react-native-sensitive-info/errors |
Typed error classes and instanceof predicates |
🎮 Example app
cd example && yarn install
yarn ios # iOS
yarn android # Android
🛠️ Development
yarn install # Install dependencies
yarn codegen # Regenerate Nitro bindings
yarn typecheck # Type-check sources
yarn build # Build distributable packages
🩺 Troubleshooting
- Biometric prompt never appears — use
canUseAccessControl(policy)to check before writing and fall back todevicePasscodeif needed. authentication failedon simulator — Secure Enclave and StrongBox are unavailable on simulators. Validate biometric policies on physical hardware.E_AUTH_CANCELEDin error message — the user dismissed the prompt. Handle gracefully; hook state is not poisoned by cancellations.- Undefined symbol on iOS — re-run
pod installafter upgrading to v6.
🤝 Contributing
Contributions are welcome!
- 🐛 Bugs — Open an issue with a minimal reproduction. Security vulnerabilities should be reported privately — see SECURITY.md.
- 💡 New features — Open an issue first to align on scope before writing code.
- 🔀 Pull requests — Run
yarn testandyarn typecheckbefore submitting. Keep changes focused and reference the relevant issue.
Please review CODE_OF_CONDUCT.md before contributing.
📄 License
MIT © Mateus Andrade
Explore related projects
freeCodeCamp/freeCodeCamp
freeCodeCamp.org's open-source codebase and curriculum. Learn math, programming, and computer science for free.
458,819 starsdonnemartin/system-design-primer
Learn how to design large-scale systems. Prep for the system design interview. Includes Anki flashcards.
377,436 starsreact/react
The library for web and native user interfaces.
252,444 starsvuejs/vue
This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core
212,624 stars