Local-First for React Native
A few years ago, the only reason to consider a local-first app architecture was if advanced offline functionality was a hard requirement for your app[1]. More recently, giving users a real-time collaborative UX (like Figma) has been enticing enough for more developers to venture down the path of local-first.
Today, the interest in building React Native apps with local-first architecture seems to be rising still. New tools and tutorials[2] make it easier than ever to get started with a local-first React Native app. There seems to be a broader paradigm shift taking place: local-first is not simply a way to provide certain features (e.g. real-time reactive UI, offline mode, real-time collaboration), but rather an architecture that avoids a lot of the complexities that come with modern cloud-first apps (e.g. caching, optimistic updates, etc.)
Part of what makes local-first appealing for React Native is that it inherently provides a simple approach to state management. There are many good state management frameworks available like Zustand, Redux and MobX, but local-first provides a different paradigm: using a local database (e.g. SQLite) to manage state [3]. Coupled with tools like Kysely (a SQL query builder) and TinyBase (a reactive in-memory data store), using a local database for state management becomes even more accessible.
React Native Local Database Options
The growing interest in local-first architectures for React Native led us to further explore the various local database options in the React Native ecosystem. Evaluating each requires diving a bit deeper into their code, and also having an idea of what you’re looking for.
We created the table below to show the main options available with key features that should help you decide which local database will work best for you. Good luck!
Preface
This breakdown only consists of local database options that provide full database functionality (persistent, consistent and queryable data stores). We ignored less-featured databases and caches. For example, we haven’t included react-native-mmkv or async-storage.
All of the below databases are open-source.
Notes On Table Columns
Type
Indicates whether the database is SQLite-based or NoSQL.
Asynchronous by Default
This indicates whether the database supports asynchronous operations; in other words, whether there is support that prevents the main thread from being blocked.
Web Support
This refers to the library being compatible with plain JavaScript web or frameworks.
Concurrency
This refers to the database’s ability to support multiple concurrent transactions.
Query Method
Here the query methods are "SQL" or "ORM" for SQLite-based databases and "domain-specific" for NoSQL databases since they each have their own query syntax flavor.
Plug-In Cloud Sync Support
This refers to the database’s ability to plug into an existing sync system that keeps data in sync with a primary cloud database and across multiple devices.
Backend Database Type
This indicates the cloud database type that the cloud sync solution supports.
Feedback
If you have feedback on this summary or have a suggestion for a feature or database to include, please let us know on our Discord server.