RxDB Server
RxDB Server is a plugin for the RxDB (Reactive Database) ecosystem, enabling server-side capabilities for RxDB databases. It allows users to spawn a server on top of an RxDB instance, providing various endpoints such as CRUD REST APIs and real-time replication endpoints. This facilitates data synchronization between client devices and the server, supporting offline-first architectures and real-time data updates. The package is designed for Node.js, Deno, Bun, or Electron's main process and can operate as a standalone server or integrate with existing HTTP frameworks like Express. Currently at version 17.1.0, it generally follows the release cadence of the main RxDB library. A key differentiator is its Server Side Public License (SSPL), similar to MongoDB's, which aims to prevent large cloud vendors from monetizing the software without contributing back. The plugin is maintained separately from the core RxDB due to its specific dependencies and licensing model.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'addCollections')
cause The RxDB database instance was not properly created or initialized before attempting to add collections.fixEnsure `createRxDatabase` is awaited and returns a valid database object before calling `db.addCollections()`. -
Error: Peer dependency 'rxdb' is not installed or mismatched version.
cause The `rxdb` package, a required peer dependency, is either missing or its version does not satisfy the `rxdb-server` requirements.fixInstall `rxdb` using `npm install rxdb` and ensure its version is compatible with `rxdb-server`. Check `npm view rxdb-server peerDependencies` for exact version ranges. -
Error: RxDB storage is not set. Add a storage like 'getRxStorageMemory()' to the database options.
cause The `createRxDatabase` function was called without a specified RxStorage plugin, which is mandatory for RxDB operation.fixImport and provide a suitable storage plugin, e.g., `getRxStorageMemory()` for in-memory, `getRxStorageDexie()` for IndexedDB in browsers, or specific Node.js storages. Example: `storage: getRxStorageMemory()`.
Warnings
- breaking The `rxdb-server` package uses the Server Side Public License (SSPL). This license restricts cloud providers from offering SSPL-licensed software as a service without a commercial license. Users should be aware of these legal implications, especially for commercial deployments where the software is offered as a service. [cite: README]
- gotcha Issues for `rxdb-server` are managed in the main `RxDB` repository. Users encountering bugs or seeking features should open issues there, not in the `rxdb-server` repository itself. [cite: README]
- breaking Since RxDB v9.0.0, all default exports were removed from the `rxdb` package and its plugins to improve tree-shaking. Imports must now use named exports, e.g., `import { createRxDatabase } from 'rxdb';`. This affects any code interacting with the core `rxdb` library, which is a peer dependency of `rxdb-server`.
- gotcha When defining schemas for RxDB collections used with `rxdb-server`, special consideration is needed for `serverOnlyFields` and `internalIndexes`. These fields might require different schema definitions on the server compared to clients to optimize server queries or hide sensitive data from clients.
- gotcha Using `rxdb-server` (or RxDB itself) in environments with bundlers like Webpack (e.g., in Angular projects) might lead to `Uncaught ReferenceError: global is not defined`. This occurs because some RxDB dependencies expect Node.js-specific global variables.
Install
-
npm install rxdb-server -
yarn add rxdb-server -
pnpm add rxdb-server
Imports
- createRxServer
import { createRxServer } from 'rxdb-server';import { createRxServer } from 'rxdb-server/plugins/server'; - RxServerAdapterExpress
import { RxServerAdapterExpress } from 'rxdb-server/adapters/express';import { RxServerAdapterExpress } from 'rxdb-server/plugins/adapter-express'; - addReplicationEndpoint
const myServer = await createRxServer(...); myServer.addReplicationEndpoint(...);
Quickstart
import { createRxDatabase, addRxPlugin } from 'rxdb';
import { getRxStorageMemory } from 'rxdb/plugins/storage-memory';
import { RxDBDevModePlugin } from 'rxdb/plugins/dev-mode';
import { createRxServer } from 'rxdb-server/plugins/server';
import { RxServerAdapterExpress } from 'rxdb-server/plugins/adapter-express';
const runServer = async () => {
// Enable dev mode for helpful warnings in development
addRxPlugin(RxDBDevModePlugin);
// Define a simple schema for our data
const mySchema = {
version: 0,
primaryKey: 'id',
type: 'object',
properties: {
id: { type: 'string', maxLength: 100 },
name: { type: 'string', maxLength: 100 },
age: { type: 'number' }
},
required: ['id', 'name']
};
// Create a RxDB database in memory for demonstration
const db = await createRxDatabase({
name: 'heroesdb',
storage: getRxStorageMemory()
});
// Add a collection
const heroesCollection = await db.addCollections({
heroes: { schema: mySchema }
});
// Insert some initial data
await heroesCollection.heroes.insert({
id: 'hero1',
name: 'SuperMan',
age: 40
});
console.log('Initial data inserted into RxDB.');
// Create the RxDB Server
const rxdbServer = await createRxServer({
database: db,
adapter: RxServerAdapterExpress,
port: 3000,
cors: true
});
// Add a replication endpoint for the 'heroes' collection
await rxdbServer.addReplicationEndpoint({
name: 'heroes-replication',
collection: heroesCollection.heroes
});
// Add a REST endpoint for basic CRUD operations
await rxdbServer.addRESTEndpoint({
name: 'heroes-rest',
collection: heroesCollection.heroes
});
// Start the server
await rxdbServer.start();
console.log('RxDB Server started on http://localhost:3000');
console.log('Replication endpoint: http://localhost:3000/heroes-replication/0');
console.log('REST endpoint (query): POST http://localhost:3000/heroes-rest/query');
};
runServer().catch(err => console.error('Error starting server:', err));