ShareJS

ShareJS is an Operational Transform library for NodeJS & browsers. It lets you easily do live concurrent editing in your app.

Here’s etherpad in 4 lines.

Everyone viewing this page can see your edits live. Open this in another browser window for maximum wow.

Code

sharejs.open('blag', 'text', function(error, doc) {
  var elem = document.getElementById('pad');
  doc.attach_textarea(elem);
});

You’re writing a web app. Your app contains data that users edit. Your users should be able to user your app from multiple computers if they need to. Sometimes you want multiple users to view & edit the same data.

How do you make that work, without the data going out of sync and without losing anything?

One option is to have Submit buttons everywhere. Stackexchange, Reddit and Hacker News work like this. You can’t write half a HN comment from your laptop and half from your phone. Most wikis have a ‘save’ button and do locking. Its like the ghostly hand of visual sourcesafe has somehow infected the web with sloppy engineering and a terrible user experience. If your wiki lock expires while you’re doing a big edit, you're in a world of hurt.

The solution is Operational Transformation (OT). If you haven’t heard of it, OT is a class of algorithms that do multi-site realtime concurrency. OT is like realtime git. It works with any amount of lag (from zero to an extended holiday). It lets users make live, concurrent edits with low bandwidth. OT gives you eventual consistency between multiple users without retries, without errors and without any data being overwritten.

Unfortunately, implementing OT sucks. There's a million algorithms with different tradeoffs, mostly trapped in academic papers. The algorithms are really hard and time consuming to implement correctly. We need some good libraries, so any project can just plug in OT if they need it.

I am an ex Google Wave engineer. Wave took 2 years to write and if we rewrote it today, it would take almost as long to write a second time. (What??)

Enter ShareJS. ShareJS is a simple (~4k LOC) coffeescript server & web client library for OT. With ShareJS, your website can let your users collaboratively edit text documents and arbitrary JSON data in realtime. (Like this one.)

As you edit the text area at the top of this page, ShareJS generates operations. Operations are like mini commits to the document. (Eg, insert:'hi', position:50.)

Like subversion, the server has a version number. If multiple users submit an operation at the same version, one of the edits is applied directly and the other user’s edit is automatically transformed by the server and then applied. Transforming is a bit like a git rebase operation.

In your browser, your edits are visible immediately. Edits from other people get transformed on top of yours. Unlike normal SCM systems, the algorithm is very careful to make sure that everyone ends up with the same document, no matter what order the operations are actually applied in. This allows the whole update & commit stuff to happen completely automatically, in realtime. There are no conflict markers or any of that jazz.

Browse through the demo gallery for more.

As well as plain text, ShareJS has OT functions defined for arbitrary JSON objects. Here’s a list of all the trains in Thomas the Tank Engine. Anyone viewing this webpage can concurrently reorder the list.

    Drag the trains around, collaboratively.

    Jeremy (who implemented the JSON OT code) wrote this multiplayer game using ShareJS. Share the URL to play with someone at a different computer.

    There’s currently nothing stopping you playing as the other team, or cheating and writing a script which moves the other player’s pieces around. You can also use the game board as a low res 3 color display and write rude messages with it. Jeremy’s game is cool.

    ShareJS is mostly working, but it’s still a bit shit. The next version will fix some connection flakiness and tell you who’s editing the document with you. I want to add rich text support as well, though I can’t find any good HTML rich text editors.

    If you’re making the next Trello or Google Spreadsheets, check out ShareJS. Make your web apps realtime and collaborative. Its the one true way ;)