Skip to main content

React Native Database

If you are looking for a React Native Database, you usually want three things:

  1. Persistence: Store data locally on the device so the app works offline.
  2. Reactivity: Automatically update the UI when data changes.
  3. Sync: Replicate data with a backend server in real-time.

RxDB covers all of these requirements out of the box. It is a local-first NoSQL database that runs deeply integrated with React Native, giving you the power of a full featured database engine inside your mobile app.

RxDB

The Storage Layerโ€‹

React Native does not have a native database engine. To store data persistently and efficiently, RxDB offers multiple powerful options.

๐Ÿ‘‘ Expo Filesystem (Highest Performance)โ€‹

For the absolute best performance in React Native and Expo applications, the premium Expo Filesystem RxStorage is highly recommended. Built on expo-opfs, it completely bypasses the React Native bridge and delivers significantly faster read/write speeds than traditional SQLite.

SQLiteโ€‹

If you prefer a free solution or specifically need SQLite, RxDB fully supports SQLite. It works on all mobile platforms and abstracts the complex SQL commands into a simple, NoSQL JSON document API.

Depending on your environment, different SQLite adapters are recommended:

For bare React Native projects, use react-native-quick-sqlite. It uses JSI (JavaScript Interface) to communicate directly with C++, effectively bypassing the slow React Native Bridge.

Installation:

npm install rxdb rxjs react-native-quick-sqlite

Configuration:

import { createRxDatabase } from 'rxdb';
import { getRxStorageSQLite, getSQLiteBasicsQuickSQLite } from 'rxdb-premium/plugins/storage-sqlite';
import { open } from 'react-native-quick-sqlite';
 
const db = await createRxDatabase({
    name: 'mydatabase',
    storage: getRxStorageSQLite({
        sqliteBasics: getSQLiteBasicsQuickSQLite(open)
    }),
    multiInstance: false,
    ignoreDuplicate: true
});

React Integrationโ€‹

RxDB is deeply integrated with React. It provides hooks that make fetching data and subscribing to changes effortless.

1. Provide the Databaseโ€‹

Wrap your application with the RxDatabaseProvider.

import { RxDatabaseProvider } from 'rxdb/plugins/react';
 
export default function App() {
  // ... create db instance
  return (
    <RxDatabaseProvider database={db}>
       <MyComponent />
    </RxDatabaseProvider>
  );
}

2. Observe Dataโ€‹

Use the useRxQuery hook (or useLiveRxQuery shortcut) to fetch data. The component will automatically re-render whenever the data in the database changes. You don't need to manually subscriptions or handling event listeners.

import { useRxCollection, useLiveRxQuery } from 'rxdb/plugins/react';
 
function TaskList() {
  const collection = useRxCollection('tasks');
  
  // This hook automatically updates 'tasks' whenever the query result changes
  const { result: tasks } = useLiveRxQuery(
    collection.find({
        selector: {
            done: { $eq: false }
        },
        sort: [{ createdAt: 'asc' }]
    })
  );
 
  return (
    <FlatList
      data={tasks}
      renderItem={({ item }) => <Text>{item.title}</Text>}
      keyExtractor={item => item.id}
    />
  );
}

3. Signals (Performance Mode)โ€‹

For high-performance applications with frequent data updates, re-rendering the entire React component might be too slow. RxDB supports Signals (via @preact/signals-react or similar) to pinpoint updates directly to the DOM nodes.

// Enable the signals plugin once
import { addRxPlugin } from 'rxdb';
import { RxDBReactivityPreactSignalsPlugin } from 'rxdb/plugins/reactivity-preact-signals';
addRxPlugin(RxDBReactivityPreactSignalsPlugin);
 
// ... in your component
const signals = collection.find().$$; // Returns a Signal<Doc[]>

Using signals allows you to update only the specific text node that changed, keeping your UI running at 60fps even with massive data flux.

Sync with Backendโ€‹

A local database is useful, but a synchronized database is powerful. RxDB provides a robust replication protocol that can sync with any backend.

It has dedicated plugins for popular backend solutions:

For custom backends, you can implement the simple HTTP replication protocol.

Example: Sync with Supabaseโ€‹

Syncing is set-and-forget. You start the replication, and RxDB handles the rest (pulling changes, pushing writes, handling conflict resolution).

import { replicateSupabase } from 'rxdb/plugins/replication-supabase';
 
const replicationState = replicateSupabase({
    replicationIdentifier: 'my-sync',
    collection: db.tasks,
    supabaseClient: supabase,
    pull: {},
    push: {},
});

Because RxDB handles the sync layer, you can build your app as if it were a purely local application. All reads and writes happen against the local SQLite database instantly, while the replication happens in the background. This is the essence of Local-First development.

Comparison with Alternativesโ€‹

How does RxDB compare to other React Native database solutions?

FeatureAsyncStorageSQLite (Raw)RealmFirestore (SDK)RxDB RxDB
TypeKey-Value StoreRelational (SQL)Object StoreCloud Document StoreNoSQL Document Store
ReactivityโŒ NoneโŒ Manual eventsโœ… Local listenersโœ… Real-time listenersโœ… Hooks / Signals / RxJS
Persistenceโœ… File (Slow)โœ… File (Generic)โœ… Custom Fileโš ๏ธ Partial Cacheโœ… SQLite / File
SyncโŒ ManualโŒ Manualโœ… Realm Sync onlyโœ… Firebase onlyโœ… Any Backend
Query EngineโŒ Noneโœ… SQL Stringsโœ… Custom APIโœ… Limitedโœ… Mango JSON Query
SchemaโŒ Noneโœ… SQL Schemaโœ… Class SchemaโŒ Looseโœ… JSON Schema
MigrationโŒ ManualโŒ Manual SQLโœ… Migration APIโŒ Noneโœ… Automatic

Summaryโ€‹

  • AsyncStorage: Good for simple key-value pairs (like settings). Too slow for data.
  • SQLite: Great foundation, but requires writing raw SQL and manual reactivity/sync.
  • Realm: Fast object store, but locks you into the MongoDB ecosystem for sync. Realm was deprecated in 2024 (source).
  • Firestore: Easy networked DB, but poor offline support (cannot start offline) and latency issues.
  • RxDB: Combines the performance of local SQLite with the ease of NoSQL, automatic reactivity, and backend-agnostic synchronization.

Ready to start? Check out the React Native Example Project or read the Quickstart Guide.