Skip to main content

RxDB - The Firestore Alternative That Can Sync with Your Own Backend

If you're seeking a Firestore alternative, you're likely looking for a way to:

  • Avoid vendor lock-in while still enjoying real-time replication.
  • Reduce cloud usage costs by reading data locally instead of constantly fetching from the server.
  • Customize how you store, query, and secure your data.
  • Implement advanced conflict resolution strategies beyond Firestore's last-write-wins approach.

Enter RxDB (Reactive Database) - a local-first, NoSQL database for JavaScript applications that can sync in real time with any backend of your choice. Whether you're tired of the limitations and fees associated with Firebase Cloud Firestore or simply need more flexibility, RxDB might be the Firestore alternative you've been searching for.

JavaScript Database

What Makes RxDB a Great Firestore Alternative?​

Firestore is convenient for many projects, but it does lock you into Google's ecosystem. Below are some of the key advantages you gain by choosing RxDB:

1. Fully Offline-First​

RxDB runs directly in your client application (browser, Node.js, Electron, React Native, etc.). Data is stored locally, so your application remains fully functional even when offline. When the device returns online, RxDB's flexible replication protocol synchronizes your local changes with any remote endpoint.

2. Freedom to Use Any Backend​

Unlike Firestore, RxDB doesn't require a proprietary hosting service. You can:

This backend-agnostic approach protects you from vendor lock-in. Your application's client-side data storage remains consistent; only your replication logic (or plugin) changes if you switch servers.

3. Advanced Conflict Resolution​

Firestore enforces a last-write-wins conflict resolution strategy. This might cause issues if multiple users or devices update the same data in complex ways.

RxDB lets you:

  • Implement custom conflict resolution via revisions.
  • Store partial merges, track versions, or preserve multiple user edits.
  • Fine-tune how your data merges to ensure consistency across distributed systems.

4. Reduced Cloud Costs​

Firestore queries often count as billable reads. With RxDB, queries run locally against your local state - no repeated network calls or extra charges. You pay only for the data actually synced, not every read. For read-heavy apps, using RxDB as a Firestore alternative can significantly reduce costs.

5. No Limits on Query Features​

Firestore's query engine is limited by certain constraints (e.g., no advanced joins, limited indexing). With RxDB:

6. True Offline-Start Support​

While Firestore does have offline caching, it often requires an online check at app initialization for authentication. RxDB is truly offline-first; you can launch the app and write data even if the device never goes online initially. It's ready whenever the user is.

7. Cross-Platform: Any JavaScript Runtime​

RxDB is designed to run in any environment that can execute JavaScript. Whether you’re building a web app in the browser, an Electron desktop application, a React Native mobile app, or a command-line tool with Node.js, RxDB’s storage layer is swappable to fit your runtime’s capabilities.

  • In the browser, store data in IndexedDB or OPFS.
  • In Node.js, use LevelDB or other supported storages.
  • In React Native, pick from a range of adapters suited for mobile devices.
  • In Electron, rely on fast local storage with zero changes to your application code.

How Does RxDB's Sync Work?​

RxDB replication is powered by its Replication Protocol. This simple yet robust protocol enables:

  1. Pull: Fetch new or updated documents from the server.
  2. Push: Send local changes back to the server.
  3. Live Real-Time: Once you're caught up, you can opt for event-based streaming instead of continuous polling.

Code Example: Sync RxDB with a Custom Backend

import { createRxDatabase } from 'rxdb/plugins/core';
import { getRxStorageDexie } from 'rxdb/plugins/storage-dexie';
import { replicateRxCollection } from 'rxdb/plugins/replication';

async function initDB() {
const db = await createRxDatabase({
name: 'mydb',
storage: getRxStorageDexie(),
multiInstance: true,
eventReduce: true
});

await db.addCollections({
tasks: {
schema: {
title: 'task schema',
version: 0,
type: 'object',
primaryKey: 'id',
properties: {
id: { type: 'string', maxLength: 100 },
title: { type: 'string' },
done: { type: 'boolean' }
}
}
}
});

// Start a custom REST-based replication
replicateRxCollection({
collection: db.tasks,
replicationIdentifier: 'my-tasks-rest-api',
push: {
handler: async (documents) => {
// Send docs to your REST endpoint
const res = await fetch('https://myapi.com/push', {
method: 'POST',
body: JSON.stringify({ docs: documents })
});
// Return conflicts if any
return await res.json();
}
},
pull: {
handler: async (lastCheckpoint, batchSize) => {
// Fetch from your REST endpoint
const res = await fetch(`https://myapi.com/pull?checkpoint=${JSON.stringify(lastCheckpoint)}&limit=${batchSize}`);
return await res.json();
}
},
live: true // keep watching for changes
});

return db;
}

By swapping out the handler implementations or using an official plugin (e.g., GraphQL, CouchDB, Firestore replication, etc.), you can adapt to any backend or data source. RxDB thus becomes a flexible alternative to Firestore while maintaining real-time capabilities.

Getting Started with RxDB as a Firestore Alternative​

Install RxDB:​

npm install rxdb rxjs

Create a Database:​

import { createRxDatabase } from 'rxdb/plugins/core';
import { getRxStorageDexie } from 'rxdb/plugins/storage-dexie';

const db = await createRxDatabase({
name: 'mydb',
storage: getRxStorageDexie()
});

Define Collections:​

await db.addCollections({
items: {
schema: {
title: 'items schema',
version: 0,
primaryKey: 'id',
type: 'object',
properties: {
id: { type: 'string', maxLength: 100 },
text: { type: 'string' }
}
}
}
});

Sync​

Use a Replication Plugin to connect with a custom backend or existing database.

For a Firestore-specific approach, RxDB Firestore Replication also exists if you want to combine local indexing and advanced queries with a Cloud Firestore backend. But if you really want to replace Firestore entirely - just point RxDB to your new backend.

Example: Start a WebRTC P2P Replication​

In addition to syncing with a central server, RxDB also supports pure peer-to-peer replication using WebRTC. This can be invaluable for scenarios where clients need to sync data directly without a master server.

import {
replicateWebRTC,
getConnectionHandlerSimplePeer
} from 'rxdb/plugins/replication-webrtc';

const replicationPool = await replicateWebRTC({
collection: db.tasks,
topic: 'my-p2p-room', // Clients with the same topic will sync with each other.
connectionHandlerCreator: getConnectionHandlerSimplePeer({
// Use your own or the official RxDB signaling server
signalingServerUrl: 'wss://signaling.rxdb.info/',

// Node.js requires a polyfill for WebRTC & WebSocket
wrtc: require('node-datachannel/polyfill'),
webSocketConstructor: require('ws').WebSocket
}),
pull: {}, // optional pull config
push: {} // optional push config
});

// The replicationPool manages all connected peers
replicationPool.error$.subscribe(err => {
console.error('P2P Sync Error:', err);
});

This example sets up a live P2P replication where any new peers joining the same topic automatically sync local data with each other, eliminating the need for a dedicated central server for the actual data exchange.

Is RxDB Right for Your Project?​

  • You want offline-first: If you need an offline-first app that starts offline, RxDB's local database approach and sync protocol excel at this.
  • Your project is read-heavy: Reading from Firestore for every query can get expensive. With RxDB, reads are free and local; you only pay for writes or sync overhead.
  • You need advanced queries: Firestore's query constraints may not suit complex data. With RxDB, you can define your own indexing logic or run arbitrary queries locally.
  • You want no vendor lock-in: Easily transition from Firestore to your own server or another vendor - just change the replication layer.

Follow Up​

If you've been searching for a Firestore alternative that gives you the freedom to sync your data with any backend, offers robust offline-first capabilities, and supports truly customizable conflict resolution and queries, RxDB is worth exploring. You can adopt it seamlessly, ensure local reads, reduce costs, and stay in complete control of your data layer.

Ready to dive in? Check out the RxDB Quickstart Guide, join our Discord community, and experience how RxDB can be the perfect local-first, real-time database solution for your next project.

More resources:

βœ•