ShareDB: Realtime JSON OT Database Backend
ShareDB is a powerful realtime database backend built on Operational Transformation (OT) for JSON documents, enabling concurrent multi-user collaboration and synchronous editing with eventual consistency. It is the core realtime backend for the DerbyJS web application framework. Currently in version 5.2.2, ShareDB maintains a consistent release cadence with frequent patch and minor updates addressing bugs and performance improvements. Key features include realtime query subscriptions, easy integration with various databases (like MongoDB via `sharedb-mongo`), horizontal scalability through pub/sub, document projections, middleware support for access control, and offline change syncing. It supports both server-side and browser environments and provides access to historic document versions and realtime user presence syncing. It differentiates itself by offering a complete OT-based solution for collaborative data management.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'db')
cause The ShareDB `Backend` was instantiated without providing a `db` option in its configuration.fixInitialize `new Backend({ db: new YourDatabaseAdapter() })`. For testing, `new MemoryDB()` can be used. -
Error: Middleware 'connection' must be a function
cause An incorrect type was passed as a middleware function for a ShareDB hook.fixEnsure that any function assigned to a middleware hook (e.g., `backend.use('connection', (request, next) => { ... })`) is indeed a function. -
ReferenceError: WebSocket is not defined (in Node.js environment)
cause The `WebSocket` class is a browser API and is not globally available in Node.js without a specific polyfill or library.fixWhen running ShareDB servers in Node.js, install and import a WebSocket library like `ws`: `import WebSocket from 'ws';`
Warnings
- breaking ShareDB v5.0.0 removed support for Node.js v16. Projects relying on older Node.js versions must upgrade their environment to Node.js v18 or newer.
- gotcha When initializing the ShareDB Backend, it is crucial to provide a database and a pub/sub adapter. Failing to do so will result in an unworkable setup, as ShareDB requires these components for persistence and real-time communication.
- gotcha ShareDB relies on a 'json0' operational transformation type by default. If you intend to use other OT types or custom operations, ensure they are registered and correctly applied, or document operations might not behave as expected.
Install
-
npm install sharedb -
yarn add sharedb -
pnpm add sharedb
Imports
- Backend
const Backend = require('sharedb');import { Backend } from 'sharedb'; - MemoryDB
import MemoryDB from 'sharedb/lib/db/memory';
import { MemoryDB } from 'sharedb'; - MemoryPubSub
import MemoryPubSub from 'sharedb/lib/pubsub/memory';
import { MemoryPubSub } from 'sharedb';
Quickstart
import { Backend, MemoryDB, MemoryPubSub } from 'sharedb';
import WebSocket from 'ws';
import http from 'http';
const backend = new Backend({
db: new MemoryDB(),
pubsub: new MemoryPubSub()
});
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('ShareDB Server\n');
});
const wss = new WebSocket.Server({ server: server });
wss.on('connection', (ws) => {
const stream = new WebSocket.WebSocketJSONStream(ws);
backend.listen(stream);
});
server.listen(8080, () => {
console.log('ShareDB server listening on http://localhost:8080');
// Example: Create a new document via a connection
const connection = backend.connect();
const doc = connection.get('myCollection', 'myDocument');
doc.fetch((err) => {
if (err) throw err;
if (doc.type === null) {
doc.create({ message: 'Hello, ShareDB!' }, 'json0', () => {
console.log('Document created:', doc.data);
});
} else {
console.log('Document already exists:', doc.data);
}
});
});
// To run this, you'll need 'ws' and 'sharedb' installed.
// For the client-side stream, you might need 'rich-websocket-jsonstream' or similar.