A maioria dos aplicativos React Native trata a rede como uma dependência sempre ativa, e isso fica evidente quando uma solicitação falha. O armazenamento offline não é uma única biblioteca — é uma pilha: armazenamentos de chave-valor para preferências, enclaves seguros para tokens, bancos de dados estruturados para dados do domínio e caches de consulta para o estado do servidor. Este post percorre toda a pilha e o padrão offline-first que a une.
The five categories of RN offline storage
- Chave-valor — AsyncStorage (compatibilidade) ou MMKV (padrão). O MMKV é ~30x mais rápido e suporta leituras sincrônicas.
- Sécurizado —
expo-secure-storeoureact-native-keychain. Apoiado pelo iOS Keychain / Android Keystore. - Estruturado —
expo-sqlite,op-sqlite(JSI, sincronização), WatermelonDB (reativo + sincronização), Realm (Atlas Device Sync). - Sistema de arquivos —
expo-file-systempara mídia. Nunca use blobs base64 em armazenamento chave-valor. - Cachê do estado do servidor — TanStack Query +
persistQueryClient, apoiado pelo MMKV.
Comparison table
| Biblioteca | Tipo | Desempenho | Criptografia | Melhor para |
|---|---|---|---|---|
| AsyncStorage | KV | 1x | Fork da comunidade | Legado/compatibilidade |
| MMKV | KV | ~30x | Inerente | Novo padrão |
| expo-secure-store | Sécurizado KV | — | Cadeia de chaves do SO | Tokens |
| op-sqlite | SQL | JSI | SQLCipher | Dados estruturados |
| WatermelonDB | Banco de dados reativo | Lento | SQLCipher | Listas offline grandes + sincronização |
| Realm | Banco de objetos | Rápido | Sim | Atlas Device Sync |
The offline-first pattern
Quatro partes em movimento:
- Leitura local-first — A UI sempre lê do armazenamento local. A rede preenche o armazenamento; o armazenamento renderiza a interface.
- Escrita otimista — A UI é atualizada imediatamente, antes que o servidor confirme.
- Fila de mutação — Lista durável (SQLite ou MMKV) de alterações pendentes no lado do servidor com IDs de cliente.
- Motor de sincronização — Trabalhador em segundo plano esvazia a fila com backoff exponencial, reconciliando conflitos.
async function marcarMensagemComoLida(id: string) {
db.write(() => {
db.Offline-first não é uma postura defensiva — é uma estratégia de desempenho. Ler do armazenamento local sempre vence uma viagem round-trip, e um bom motor de sincronização esconde a rede dos seus usuários. Escolha cada camada deliberadamente e isso se torna um problema resolvido, não um recorrente.
Eu construí RapidNative, um construtor de aplicativos móveis baseado em IA que gera código React Native pronto para produção que você pode estender com qualquer uma dessas bibliotecas. Gostaria de feedback de quem está usando MMKV + TanStack Query em produção.

