{"id":16497,"library":"pouchdb-replicator","title":"PouchDB Replicator Plugin","description":"pouchdb-replicator is a PouchDB plugin that simulates the functionality of CouchDB's `_replicator` database daemon. Instead of initiating one-off or programmatic replication calls (e.g., `db.replicate()`), this plugin allows developers to define and manage persistent replication jobs declaratively by simply writing documents to a special `_replicator` database. This enables scenarios like continuous synchronization across application restarts and simplifies the management of complex replication topologies. The current stable version is 4.2.0, part of the pouchdb-server monorepo. It receives regular maintenance updates, focusing on bug fixes, dependency updates, and minor enhancements. Its key differentiator is providing a CouchDB-compatible declarative replication interface directly within PouchDB, making it ideal for applications requiring robust offline-first capabilities and seamless synchronization with CouchDB or other PouchDB instances.","status":"active","version":"4.2.0","language":"javascript","source_language":"en","source_url":"https://github.com/pouchdb/pouchdb-server","tags":["javascript","pouch","pouchdb","couch","couchdb","replication","replicator","replicate"],"install":[{"cmd":"npm install pouchdb-replicator","lang":"bash","label":"npm"},{"cmd":"yarn add pouchdb-replicator","lang":"bash","label":"yarn"},{"cmd":"pnpm add pouchdb-replicator","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"This package is a PouchDB plugin and extends the core PouchDB object.","package":"pouchdb","optional":false}],"imports":[{"note":"The primary way to use this plugin is to import its default export and register it with `PouchDB.plugin()`. Ensure `pouchdb` itself is imported correctly first. While CommonJS is shown as 'wrong' for modern contexts, it's still prevalent in older Node.js projects, but ESM is preferred for PouchDB since v7.","wrong":"const PouchDB = require('pouchdb');\nconst PouchDBReplicator = require('pouchdb-replicator'); // CommonJS for older Node","symbol":"PouchDBReplicator","correct":"import PouchDB from 'pouchdb';\nimport PouchDBReplicator from 'pouchdb-replicator';"},{"note":"PouchDB plugins must be registered with the global `PouchDB` object using the `.plugin()` method for their functionality to become available on database instances.","wrong":"new PouchDBReplicator();\n// or just importing without registering","symbol":"PouchDB.plugin","correct":"PouchDB.plugin(PouchDBReplicator);"},{"note":"`PouchDB` is typically imported as a default export, even though it exposes many named utilities. Forgetting to import it, or importing it incorrectly, will prevent plugin registration.","wrong":"import { PouchDB } from 'pouchdb';\n// or not importing it at all","symbol":"PouchDB","correct":"import PouchDB from 'pouchdb';"}],"quickstart":{"code":"import PouchDB from 'pouchdb';\nimport PouchDBReplicator from 'pouchdb-replicator';\n\n// Register the PouchDB Replicator plugin\nPouchDB.plugin(PouchDBReplicator);\n\nasync function setupPersistentReplication() {\n  // Initialize a local PouchDB database\n  const localDb = new PouchDB('my_local_db');\n\n  // Define a remote PouchDB/CouchDB instance URL\n  const remoteDbUrl = 'http://localhost:5984/my_remote_db'; // Ensure CouchDB is running or this is a valid PouchDB instance\n\n  // The special _replicator database to manage replication jobs\n  const replicatorDb = new PouchDB('_replicator');\n\n  try {\n    // Create a continuous replication job by posting a document to _replicator\n    // This will instruct PouchDB-Replicator to start and manage the replication.\n    const replicationJob = {\n      _id: 'my-first-continuous-sync',\n      source: localDb.name,        // Source database: 'my_local_db'\n      target: remoteDbUrl,       // Target database: 'http://localhost:5984/my_remote_db'\n      continuous: true,          // Keep replication running continuously\n      live: true,                // Also track future changes (often implied by continuous)\n      retry: true,               // Automatically retry on failure\n      // For authenticated replication to a remote CouchDB:\n      // auth: {\n      //   username: process.env.COUCHDB_USERNAME ?? 'admin',\n      //   password: process.env.COUCHDB_PASSWORD ?? 'password'\n      // }\n    };\n\n    const response = await replicatorDb.put(replicationJob);\n    console.log('Replication job started successfully:', response);\n\n    // To stop or update the replication, you would modify or delete this document from _replicator\n    // e.g., await replicatorDb.remove(response.id, response.rev);\n\n  } catch (error: any) {\n    console.error('Failed to set up replication job:', error);\n    // Handle common errors like network issues, authentication failures, etc.\n  }\n}\n\nsetupPersistentReplication();","lang":"typescript","description":"This quickstart demonstrates how to register `pouchdb-replicator` as a plugin and then initiate a continuous replication job by creating a document in the special `_replicator` database. This simulates CouchDB's declarative replication management."},"warnings":[{"fix":"Review the full `pouchdb-server` 4.0.0 changelog for details on monorepo migration and dependency impacts. Ensure all related PouchDB packages are compatible with this new structure.","message":"Version 4.0.0 was the first release built from a complete monorepo, changing internal structures and dependencies. It also addressed a security issue. While the impact on direct API usage for `pouchdb-replicator` itself might be minimal, users upgrading from pre-4.0.0 versions should be aware of potential broader ecosystem changes within `pouchdb-server`.","severity":"breaking","affected_versions":">=4.0.0 <4.0.1"},{"fix":"For affected database names, migration may involve renaming database files or adjusting how names are handled. Ensure PouchDB is updated to a version where issue 2442 is solved to support the prefixed replication fields.","message":"Version 2.0.0 introduced breaking changes that correspond to `express-pouchdb` 2.0.0, specifically impacting database name encoding for adapters that store files. If database names contained '/' characters, existing databases might not be found. Additionally, version 2.0.0 onward uses prefixed replication fields (`_replication_state` instead of `replication_state`).","severity":"breaking","affected_versions":">=2.0.0 <3.0.0"},{"fix":"Upgrade to `pouchdb-replicator@4.1.0` or later to benefit from the memory leak fix.","message":"A potential `EventEmitter` memory leak issue was fixed in version 4.1.0 (#233). Applications with many active replications or frequent replication job changes might have experienced memory consumption growth over time in earlier versions.","severity":"gotcha","affected_versions":">=2.0.0 <4.1.0"},{"fix":"Upgrade to `pouchdb-replicator@4.2.0` or later to ensure proper error reporting for `.info` calls.","message":"Version 4.2.0 fixed an issue where `.info` errors were being swallowed, leading to silent failures or missed diagnostic information during replication.","severity":"gotcha","affected_versions":">=4.0.0 <4.2.0"},{"fix":"Adopt ES Module syntax (`import ... from '...'`) throughout your project. If bundling for older environments, ensure your build setup correctly transpiles ESM to CJS.","message":"PouchDB (and by extension its plugins like `pouchdb-replicator`) has evolved towards ESM. While older versions might support CommonJS, modern PouchDB usage (especially with recent versions like v7+) strongly encourages ESM for better compatibility and tree-shaking.","severity":"breaking","affected_versions":">=7.0.0 (PouchDB)"},{"fix":"For new projects with extreme performance requirements or specific modern sync patterns (e.g., WebRTC, GraphQL), evaluate alternative RxDB storage engines. For existing PouchDB applications, continue using `pouchdb-replicator` but be mindful of its inherent characteristics.","message":"The broader PouchDB ecosystem has seen significant shifts, with some perspectives considering PouchDB legacy for high-performance use cases due to revision handling overhead and bundle size. While `pouchdb-replicator` remains functional, consider the long-term architectural implications if performance or strict modern database standards are critical.","severity":"deprecated","affected_versions":">=4.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Ensure `import PouchDB from 'pouchdb';` is at the top of your file and that `PouchDB.plugin(PouchDBReplicator);` is called after PouchDB is ready.","cause":"The PouchDB library was either not imported, imported incorrectly (e.g., named import instead of default), or the `PouchDB.plugin()` method was called before the PouchDB object was properly initialized.","error":"TypeError: PouchDB.plugin is not a function"},{"fix":"Double-check the `source` and `target` URLs/names in your `_replicator` document. If replicating to a remote CouchDB, ensure `auth` options (username, password) are correctly provided in the replication document, or the user has appropriate roles set up.","cause":"This error typically occurs during replication if the source or target database URL is incorrect, the database does not exist, or there are insufficient authentication credentials/permissions to access the remote database.","error":"Error: Database not found or permission denied"},{"fix":"Before updating a replication document, fetch its current `_rev` (e.g., via `replicatorDb.get(id)`), then include that `_rev` in your `put()` or `post()` call. Alternatively, use a PouchDB upsert plugin if available.","cause":"When updating a replication document in the `_replicator` database, you must provide the correct `_rev` of the existing document. If the `_rev` is missing or stale, a conflict will occur.","error":"Error: Document update conflict"},{"fix":"Ensure that `new PouchDB('db_name')` calls are awaited or handled as promises, and that the resulting PouchDB objects are valid before being used in the replication document.","cause":"If `source` or `target` are PouchDB database objects instead of names/URLs, this error suggests that the PouchDB instance itself (e.g., `localDb` in the quickstart) was not properly initialized or is `undefined` when its `.name` property is accessed.","error":"TypeError: Cannot read properties of undefined (reading 'name') on 'source' or 'target'"}],"ecosystem":"npm"}