What is AsyncStorage?
When you close an app and reopen it, your preferences, login state, and draft content should still be there. This is data persistence, and AsyncStorage is React Native's go-to solution for this essential functionality.
AsyncStorage is an asynchronous, unencrypted, persistent, key-value storage system that is global to your React Native application. Think of it as your app's personal pocket--a place to stash small, important things like user tokens, settings, or draft content.
Originally part of React Native core, AsyncStorage was moved to a community-maintained package to provide better flexibility and maintenance. This change allows the library to evolve independently while maintaining compatibility across different React Native versions. For teams building mobile applications with React Native, mastering AsyncStorage is essential for creating apps that feel responsive and remember user preferences.
Persistent
Data survives app restarts and OS-level operations
Key-Value Storage
Simple dictionary-style interface for storing data
Asynchronous
Non-blocking operations using Promises
Cross-Platform
Works identically on iOS and Android
Installation and Setup
Installing the Package
For Expo projects:
npx expo install @react-native-async-storage/async-storage
For bare React Native projects:
npm install @react-native-async-storage/async-storage
cd ios && pod install
Importing the Library
import AsyncStorage from '@react-native-async-storage/async-storage';
Proper installation is the foundation of any React Native mobile application. Once installed, AsyncStorage provides a reliable way to persist user data across app sessions. Our web development team regularly implements these patterns when building cross-platform mobile solutions that require offline-first capabilities.
Core API Methods
Storing Data with setItem
const storeUserToken = async (token: string) => {
try {
await AsyncStorage.setItem('user_token', token);
console.log('Token saved successfully!');
} catch (e) {
console.error('Failed to save the token.', e);
}
};
Reading Data with getItem
const getUserToken = async () => {
try {
const token = await AsyncStorage.getItem('user_token');
if (token !== null) {
console.log('Token retrieved:', token);
return token;
}
return null;
} catch (e) {
console.error('Failed to fetch token.', e);
return null;
}
};
Removing Data with removeItem
const removeUserToken = async () => {
try {
await AsyncStorage.removeItem('user_token');
console.log('Token removed successfully');
} catch (e) {
console.error('Failed to remove token.', e);
}
};
Clearing All Data
const clearAllStorage = async () => {
try {
await AsyncStorage.clear();
console.log('Storage cleared completely');
} catch (e) {
console.error('Failed to clear storage.', e);
}
};
These core methods form the foundation of data persistence in any mobile app built with React Native. Understanding how to properly use setItem, getItem, and removeItem is essential for building robust user experiences that maintain state across sessions.
Storing Complex Data Types
Since AsyncStorage only accepts strings, complex data structures require serialization using JSON.
Storing Objects
interface UserSettings {
theme: 'light' | 'dark';
notifications: boolean;
language: string;
}
const saveUserSettings = async (settings: UserSettings) => {
try {
await AsyncStorage.setItem('user_settings', JSON.stringify(settings));
} catch (e) {
console.error('Failed to save settings.', e);
}
};
const loadUserSettings = async (): Promise<UserSettings | null> => {
try {
const settingsJSON = await AsyncStorage.getItem('user_settings');
return settingsJSON ? JSON.parse(settingsJSON) : null;
} catch (e) {
console.error('Failed to load settings.', e);
return null;
}
};
Storing Arrays
const saveTodoList = async (todos: Todo[]) => {
try {
await AsyncStorage.setItem('todos', JSON.stringify(todos));
} catch (e) {
console.error('Failed to save todos.', e);
}
};
const loadTodoList = async (): Promise<Todo[]> => {
try {
const todosJSON = await AsyncStorage.getItem('todos');
return todosJSON ? JSON.parse(todosJSON) : [];
} catch (e) {
console.error('Failed to load todos.', e);
return [];
}
};
JSON serialization is a pattern you'll use frequently when building React Native applications. This approach allows you to store rich, structured data while maintaining the simplicity of AsyncStorage's key-value interface. Our developers often combine these patterns with custom software development practices to create robust data management solutions.
Real-World Use Cases
User Authentication State
const onLoginSuccess = async (token: string) => {
await AsyncStorage.setItem('auth_token', token);
};
const checkAuthState = async () => {
const token = await AsyncStorage.getItem('auth_token');
return !!token;
};
const logout = async () => {
await AsyncStorage.removeItem('auth_token');
};
App Preferences and Settings
const toggleTheme = async (theme: 'light' | 'dark') => {
await AsyncStorage.setItem('app_theme', theme);
};
Offline Data Caching
const cacheApiResponse = async (key: string, data: any, maxAge: number) => {
const cacheEntry = { data, timestamp: Date.now(), maxAge };
await AsyncStorage.setItem(`cache_${key}`, JSON.stringify(cacheEntry));
};
Form Draft Auto-Save
const saveFormDraft = async (formData: any) => {
await AsyncStorage.setItem('form_draft', JSON.stringify(formData));
};
These patterns are essential for building professional mobile applications that provide seamless user experiences. Whether you're implementing offline-first capabilities or preserving user progress, AsyncStorage provides the foundation for reliable data persistence that users expect from modern apps.
Secure Alternatives for Sensitive Data
For sensitive information, use dedicated secure storage solutions:
react-native-keychain - For passwords and biometric authentication:
npm install react-native-keychain
react-native-encrypted-storage - For encrypted key-value pairs:
npm install react-native-encrypted-storage
Expo SecureStore - For Expo projects:
import * as SecureStore from 'expo-secure-store';
await SecureStore.setItemAsync('secret', value);
Security is paramount when building any professional mobile application. Understanding when to use AsyncStorage versus secure storage alternatives is a critical decision in your app architecture. For enterprise-grade solutions, our AI automation services can help integrate intelligent security patterns into your mobile development workflow.
Use Key Prefixing
Prevent namespace collisions with prefixes like '@myapp/'
Always Handle Errors
Wrap operations in try-catch to handle disk full and permission issues
Mind Storage Limits
Around 6MB on Android, 50MB on iOS. Implement cleanup strategies
Use merge for Updates
Use multiMerge or individual merges for partial object updates
Frequently Asked Questions
What is the storage limit for AsyncStorage?
No official limit, but typically ~6MB on Android and up to 50MB on iOS. Treat it as limited storage.
Is AsyncStorage synchronous or asynchronous?
Fully asynchronous. All methods return Promises and can be used with async/await.
Does data persist after app uninstall?
No, AsyncStorage data is cleared when the app is uninstalled.
How do I handle development mode quirks?
During Fast Refresh, data may appear lost. This is development-only; data persists correctly in production builds.
Conclusion
AsyncStorage is a deceptively simple tool that forms the backbone of data persistence in countless React Native applications. Its strengths--persistence, simplicity, and asynchronicity--make it ideal for storing non-sensitive key-value data like user preferences, cached content, and session tokens.
However, respecting its limitations is equally important: it is not secure storage, not a database, and not designed for large datasets. By understanding both its capabilities and constraints, you can leverage AsyncStorage effectively to build more robust, user-friendly, and professional mobile applications.
When building React Native apps that require data persistence, AsyncStorage provides a reliable foundation. For projects requiring more advanced data management, consider how our web development services can help you architect the right solution for your specific needs. Our team specializes in building cross-platform applications that leverage modern persistence patterns for optimal user experiences.