{"id":16530,"library":"share","title":"ShareJS - Concurrent Document Editing","description":"ShareJS is a server and client library designed for real-time, concurrent document editing using operational transformation (OT). It supports OT on plain-text and arbitrary JSON data, allowing multiple users to collaborate on content simultaneously. The server component runs on Node.js, while the client library functions in both Node.js and web browsers, aiming for broad browser compatibility. It depends on LiveDB for its database backend and data model, and explicitly requires developers to provide a communication transport layer that guarantees in-order message delivery, warning against common pitfalls like using Socket.IO without careful configuration. The current stable version mentioned is 0.7.40. Key differentiators include its transport-agnostic design and its focus on raw OT primitives, leaving UI implementation to the developer. The project appears to be unmaintained as of early 2026, with no recent activity on its GitHub repository since around 2017.","status":"abandoned","version":"0.7.40","language":"javascript","source_language":"en","source_url":"http://github.com/josephg/sharejs","tags":["javascript","operational transformation","ot","concurrent","collaborative","database","server"],"install":[{"cmd":"npm install share","lang":"bash","label":"npm"},{"cmd":"yarn add share","lang":"bash","label":"yarn"},{"cmd":"pnpm add share","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required for ShareJS's database backend and data model. ShareJS uses LiveDB clients to interact with various data stores (e.g., in-memory, MongoDB).","package":"livedb","optional":false},{"reason":"A recommended transport layer for client-server communication, providing the necessary in-order message delivery guarantee that ShareJS requires. While optional, a compatible transport is mandatory.","package":"node-browserchannel","optional":true}],"imports":[{"note":"ShareJS and its dependencies are primarily CommonJS modules. ESM 'import' syntax is not supported in this version.","wrong":"import livedb from 'livedb';","symbol":"livedb","correct":"var livedb = require('livedb');"},{"note":"The main ShareJS library is imported via CommonJS 'require'. The 'share' object itself provides access to the server and other utilities.","wrong":"import share from 'share';","symbol":"share","correct":"var share = require('share');"},{"note":"The server instance factory method `createClient` is nested under the `server` property of the main `share` export.","wrong":"var shareServer = require('share').createClient({backend: backend});","symbol":"createClient","correct":"var shareServer = require('share').server.createClient({backend: backend});"}],"quickstart":{"code":"const livedb = require('livedb');\nconst share = require('share');\nconst http = require('http');\nconst express = require('express');\nconst WebSocket = require('ws');\n\n// 1. Initialize LiveDB backend (in-memory for simple example)\nconst backend = livedb.client(livedb.memory());\n\n// 2. Create ShareJS server instance\nconst shareServer = share.server.createClient({backend: backend});\n\n// 3. Set up HTTP server for serving client-side code (optional, but common)\nconst app = express();\napp.use(express.static(__dirname + '/public')); // Serve static files\n\nconst httpServer = http.createServer(app);\nconst wss = new WebSocket.Server({ server: httpServer });\n\n// 4. Handle WebSocket connections for ShareJS clients\nwss.on('connection', (ws) => {\n  const stream = WebSocket.createWebSocketStream(ws);\n  shareServer.listen(stream);\n  console.log('New ShareJS client connected via WebSocket.');\n});\n\nconst PORT = process.env.PORT || 8000;\nhttpServer.listen(PORT, () => {\n  console.log(`ShareJS server listening on http://localhost:${PORT}`);\n  console.log('You will need a client-side implementation to connect.');\n});","lang":"javascript","description":"This quickstart initializes a ShareJS server with an in-memory LiveDB backend and sets up a WebSocket server to handle client connections, demonstrating the basic server-side setup."},"warnings":[{"fix":"Evaluate actively maintained alternatives like Yjs, Automerge, or other collaborative editing frameworks. If continuing with ShareJS, be prepared to fork and maintain the codebase yourself.","message":"The ShareJS project, including its core repository (share/ShareJS), appears to be abandoned. The last significant commit was around 2017. Users should be aware that there will likely be no further bug fixes, security patches, or feature development. Consider alternative, actively maintained operational transformation libraries.","severity":"breaking","affected_versions":">=0.7.40"},{"fix":"Utilize transports known to guarantee message order, such as `node-browserchannel`, or carefully configure your chosen WebSocket library (e.g., `ws`) to ensure strict ordering. Do not rely on `socket.io`'s default behavior for ShareJS communication without thoroughly understanding its ordering guarantees.","message":"ShareJS requires a communication transport that guarantees in-order message delivery. Using libraries like `socket.io` directly without specific configuration can lead to messages arriving out of order, causing data corruption or synchronization issues.","severity":"gotcha","affected_versions":">=0.6.0"},{"fix":"Remember that `require('share').server.createClient()` is the correct way to instantiate the ShareJS server component. The 'client' in the name refers to its interaction with the underlying LiveDB database.","message":"The server-side API method to create a ShareJS instance is named `createClient`, which can be confusing as it creates a 'server' object that acts as a client to the LiveDB backend. This naming choice is explicit in the documentation but often leads to initial confusion.","severity":"gotcha","affected_versions":">=0.6.0"},{"fix":"Refer to the linked repositories on GitHub for the most current (though potentially outdated) documentation for `share.rest()` and `share.use()`. Be prepared to examine the source code for undocumented behaviors.","message":"Documentation for the REST API and middleware (`share.use`) is partially external or incomplete within the main ShareJS repository. Users may need to consult separate repositories (`share/rest`, `share/middleware`) for full details, which might also suffer from the overall lack of maintenance.","severity":"gotcha","affected_versions":">=0.6.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Run `npm install share` in your project directory to install the package.","cause":"The 'share' package has not been installed or is not resolvable in the current environment.","error":"Error: Cannot find module 'share'"},{"fix":"Run `npm install livedb` in your project directory. Depending on your chosen storage, you might also need `livedb-mongo` or similar.","cause":"The 'livedb' package, a mandatory dependency for ShareJS, has not been installed.","error":"Error: Cannot find module 'livedb'"},{"fix":"Ensure you are using `var share = require('share');` and then `share.server.createClient(...)`. Double-check the exact casing and property access.","cause":"Attempting to call `createClient` directly on the `share` module or `share.server` without properly requiring the `share` module, or using incorrect import syntax.","error":"TypeError: require(...).server.createClient is not a function"},{"fix":"Migrate to a transport like `node-browserchannel` or ensure your WebSocket implementation explicitly enforces in-order message delivery. Avoid relying on default Socket.IO behavior for ShareJS.","cause":"Socket.IO, by default, does not guarantee in-order message delivery, which is a strict requirement for ShareJS's operational transformation to function correctly.","error":"Data synchronization errors or corrupted documents with Socket.IO"}],"ecosystem":"npm"}