{"id":16527,"library":"rxdb","title":"RxDB","description":"RxDB (Reactive Database) is a local-first, NoSQL database designed for JavaScript applications, including websites, hybrid apps, Electron, Progressive Web Apps, and Node.js. Currently stable at version 17.1.0, it follows a release cadence with frequent beta cycles leading to major versions and subsequent point releases for bug fixes. Its core differentiator is its reactive architecture, leveraging RxJS to provide observable queries and real-time data changes. RxDB supports offline-first operation, enforces data integrity through JSONSchema-based validation, and offers a highly pluggable synchronization engine for diverse backends like HTTP, GraphQL, WebRTC (P2P), CouchDB, MongoDB, Supabase, and even serverless options such as Google Drive and Microsoft OneDrive. Key features include conflict resolution (e.g., CRDTs), encryption, and robust data migration capabilities for evolving schemas and underlying storage adapters, ensuring data consistency across multiple client instances and browser tabs.","status":"active","version":"17.1.0","language":"javascript","source_language":"en","source_url":"https://github.com/pubkey/rxdb","tags":["javascript","db","database","offline-first","local-first","local first","nosql","no-sql","jsonschema","typescript"],"install":[{"cmd":"npm install rxdb","lang":"bash","label":"npm"},{"cmd":"yarn add rxdb","lang":"bash","label":"yarn"},{"cmd":"pnpm add rxdb","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core dependency for reactive programming model (observables)","package":"rxjs","optional":false},{"reason":"Optional, for integration with Angular applications","package":"@angular/core","optional":true},{"reason":"Optional, for integration with Preact Signals","package":"@preact/signals-core","optional":true},{"reason":"Optional, for integration with React applications","package":"react","optional":true},{"reason":"Optional, for integration with Vue.js applications","package":"vue","optional":true},{"reason":"Optional, for Firebase replication or storage adapter","package":"firebase","optional":true},{"reason":"Optional, for MongoDB storage or replication adapter in Node.js","package":"mongodb","optional":true},{"reason":"Optional, for NATS replication adapter","package":"nats","optional":true}],"imports":[{"note":"RxDB v9+ removed default exports. All core functions are named exports from 'rxdb'.","wrong":"const createRxDatabase = require('rxdb');\nimport RxDB from 'rxdb';","symbol":"createRxDatabase","correct":"import { createRxDatabase } from 'rxdb';"},{"note":"Plugins are added via `addRxPlugin`. For specific plugins, import the plugin itself from its dedicated path, e.g., `import { RxDBDevModePlugin } from 'rxdb/plugins/dev-mode';`","wrong":"const addRxPlugin = require('rxdb').addRxPlugin;\nimport { addRxPlugin } from 'rxdb/plugins/core';","symbol":"addRxPlugin","correct":"import { addRxPlugin } from 'rxdb';"},{"note":"Storage adapters and most other plugins are imported from their specific plugin paths under `rxdb/plugins/`.","wrong":"import { getRxStorageDexie } from 'rxdb';","symbol":"getRxStorageDexie","correct":"import { getRxStorageDexie } from 'rxdb/plugins/storage-dexie';"},{"note":"Use `import type` for TypeScript interfaces and types to ensure they are stripped from the JavaScript bundle.","wrong":"import { RxJsonSchema } from 'rxdb';","symbol":"RxJsonSchema","correct":"import type { RxJsonSchema } from 'rxdb';"}],"quickstart":{"code":"import { createRxDatabase, addRxPlugin } from 'rxdb';\nimport { getRxStorageDexie } from 'rxdb/plugins/storage-dexie';\nimport { RxDBDevModePlugin } from 'rxdb/plugins/dev-mode';\n\n// Add dev mode plugin in development for better error messages\nif (process.env.NODE_ENV !== 'production') {\n  addRxPlugin(RxDBDevModePlugin);\n}\n\nasync function runRxDBQuickstart() {\n  const mySchema = {\n    version: 0,\n    primaryKey: 'id',\n    type: 'object',\n    properties: {\n      id: { type: 'string', maxLength: 100 },\n      title: { type: 'string' },\n      done: { type: 'boolean', default: false }\n    },\n    required: ['id', 'title', 'done']\n  };\n\n  const db = await createRxDatabase({\n    name: 'mydatabase',\n    storage: getRxStorageDexie(),\n    multiInstance: true // Enable multi-tab synchronization\n  });\n\n  await db.addCollections({\n    todos: {\n      schema: mySchema\n    }\n  });\n\n  // Insert a document\n  await db.todos.insert({\n    id: 'todo-1',\n    title: 'Learn RxDB',\n    done: false\n  });\n\n  // Query documents\n  const allTodos = await db.todos.find().exec();\n  console.log('All todos:', allTodos.map(doc => doc.toJSON()));\n\n  // Subscribe to changes (reactive query)\n  const subscription = db.todos.find({\n    selector: { done: false }\n  }).$.subscribe(undoneTodos => {\n    console.log('Undone todos changed:', undoneTodos.map(doc => doc.toJSON()));\n  });\n\n  // Update a document\n  const todoToUpdate = await db.todos.findOne('todo-1').exec();\n  if (todoToUpdate) {\n    await todoToUpdate.patch({ done: true });\n  }\n\n  // Wait a moment for subscription to react and then clean up\n  setTimeout(async () => {\n    subscription.unsubscribe();\n    await db.destroy();\n    console.log('Database destroyed.');\n  }, 1000);\n}\n\nrunRxDBQuickstart();","lang":"typescript","description":"This quickstart demonstrates how to create an RxDB database, define a schema, add a collection, insert and query documents, and subscribe to real-time changes using the Dexie storage adapter. It also shows the conditional inclusion of the DevMode plugin for development."},"warnings":[{"fix":"Consult the RxDB v17 migration guide (rxdb.info/releases/17.0.0.html) and use the Storage Migration Plugin to safely transfer your existing data to the new format or storage. The Storage Migration Plugin is now part of open-core since v15.","message":"Upgrading to RxDB v17 requires data migration for users of OPFS, Filesystem, or IndexedDB RxStorages. The underlying data storage format for IndexedDB, for example, changed to binary to reduce disk space usage. Ensure you follow the storage migration guide when updating from v16 to v17 for these specific storages.","severity":"breaking","affected_versions":">=17.0.0"},{"fix":"Migrate your existing PouchDB-based RxDB applications to another RxStorage, such as `getRxStorageDexie` or `getRxStorageIndexeddb` (for browser environments), or `getRxStorageMongoDB` (for Node.js). The Storage Migration Plugin can assist with this transition.","message":"The PouchDB RxStorage is officially deprecated and removed from the RxDB core since v15. It is no longer recommended for new projects and will not be maintained. Its use can lead to performance drawbacks and hinder access to newer RxDB features.","severity":"breaking","affected_versions":">=15.0.0"},{"fix":"Update your JSON schemas to include a `primaryKey` property at the top level, specifying the field that serves as the unique identifier for documents in the collection.","message":"Since RxDB v10, a `primaryKey` is explicitly required in all RxCollection schemas. Omitting it will cause an error. Previously, RxDB would automatically use an internal `_id` field if `primaryKey` was not specified.","severity":"breaking","affected_versions":">=10.0.0"},{"fix":"Conditionally add `RxDBDevModePlugin` only in development environments (e.g., `if (process.env.NODE_ENV !== 'production') { addRxPlugin(RxDBDevModePlugin); }`).","message":"The `DevMode` plugin (RxDBDevModePlugin) is essential for development as it adds comprehensive checks, validations, and human-readable error messages. However, it significantly increases bundle size and can decrease runtime performance. It must never be included in production builds.","severity":"gotcha","affected_versions":">=0.0.0"},{"fix":"Ensure all `addRxPlugin()` calls for necessary plugins (e.g., storage adapters, dev mode, replication) are executed synchronously before initializing your RxDatabase instance.","message":"All RxDB plugins must be registered using `addRxPlugin()` *before* any `createRxDatabase()` call. Failing to do so will result in plugins not being activated, leading to missing functionality or errors when trying to use plugin-provided features.","severity":"gotcha","affected_versions":">=0.0.0"},{"fix":"If you need to modify data retrieved from RxDB, create your own deep clone of the document objects before making any changes.","message":"Since RxDB v10, outgoing data (e.g., results from `find()` queries) is no longer deep-cloned but assumed to be immutable. Direct mutation of these returned objects might lead to unexpected internal behavior or inconsistencies, as RxDB itself may use these references.","severity":"gotcha","affected_versions":">=10.0.0"},{"fix":"For WebViews and native desktop/mobile applications, prefer robust storage solutions like SQLite-based RxStorages (often premium features) over IndexedDB to ensure data persistence and integrity.","message":"When using RxDB in WebViews (e.g., within React Native or Electron mobile builds), IndexedDB-based storages can be unreliable, leading to data loss, corruption, or unexpected resets. This is due to WebView limitations regarding storage stability and background process handling.","severity":"gotcha","affected_versions":">=0.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"In development, enable the `RxDBDevModePlugin` (`addRxPlugin(RxDBDevModePlugin)`) to receive full, human-readable error messages including cause, fix suggestions, and documentation links. For production errors, refer to the RxDB documentation using the error code.","cause":"RxDB throws specific error objects with codes; detailed messages are omitted in production builds for bundle size.","error":"RxError: DB1 (or other RxError: <CODE>)"},{"fix":"Ensure your environment supports `crypto.subtle.digest` (Node.js >=18, browser on HTTPS/localhost). Alternatively, provide a custom `hashFunction` option when creating the database if `crypto.subtle` is unavailable or problematic.","cause":"This error typically indicates that the JavaScript runtime environment (e.g., some WebViews, older Node.js versions) lacks support for `crypto.subtle.digest`, or access is blocked (e.g., browser running on HTTP instead of HTTPS/localhost).","error":"TypeError: Cannot read properties of undefined (reading 'digest')"},{"fix":"Review your application's initialization code to ensure each RxDB plugin is added only once. Check your dependency tree for duplicate package installations if this persists.","cause":"You are attempting to call `addRxPlugin()` with the same plugin more than once, or there are multiple instances/versions of the same plugin in your application bundle.","error":"RxError: PL3 (A plugin with the same name has already been added.)"},{"fix":"Always increment the `version` property in your schema definition when making structural changes. If existing data needs to be transformed, define `migrationStrategies` when adding the collection to handle data updates from previous schema versions.","cause":"The schema definition provided for a collection does not match the schema version already stored in the database. This usually happens when you modify a schema but forget to increment its `version` number.","error":"RxError: DB6 (The schema hash does not match the schema stored in the internal database.)"},{"fix":"Ensure that any document you insert or upsert explicitly includes the field defined as the `primaryKey` in your RxCollection's schema. This field is mandatory for document identification.","cause":"The document object passed to `upsert()` or `insert()` is missing the field designated as the `primaryKey` in your collection's schema.","error":"RxError: COL3 (You called upsert() but the document data does not contain the primary key.)"}],"ecosystem":"npm"}