TogetherJS: Adding Real-Time Collaboration to Any Website
A service for your website that makes it surprisingly easy to collaborate in real-time.
At a glance
- What is it?
- TogetherJS is a JavaScript library that lets two visitors on the same web page see each other's mouse cursors, observe form input in real time, and communicate through a built-in chat interface. The original shared relay server no longer exists, so every deployment requires a self-hosted hub.
- Who is it for?
- TogetherJS suits developers who want to add a lightweight collaboration layer to an existing HTML page without redesigning it around a shared data model. The installation overhead is moderate, but the hub requirement is real: every production deployment needs a relay server, and hub-worker/ on Cloudflare Workers is the only self-contained option the repository provides.
- Can I use it commercially?
- Yes, with conditions. MPL-2.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 19 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What TogetherJS Does and Who Should Use It
TogetherJS is a drop-in JavaScript library that adds real-time awareness to a web page. When two users are connected through a TogetherJS session, each can see the other's cursor moving across the page, watch form fields being filled in, and observe scroll position. A text chat panel and an audio link are also available. The intended audience is web developers who build support workflows, pair-programming tools, co-registration forms, or customer service interfaces where an agent must walk a user through a page step by step. The library is embedded by the site owner, not installed by the visitor. A user starts a session and shares a link; the second person clicks the link and both are connected. Unlike screen-sharing software such as Zoom or Google Meet, TogetherJS operates entirely within the browser context of a single page, which means it requires no plugin and no operating-system permission.
Client and Hub: The Two Parts of TogetherJS
TogetherJS divides its work between two independent components. The client, which lives in the togetherjs/ directory, runs in the user's browser. It handles cursor tracking, DOM mutation broadcasting, form field synchronization, and the chat user interface. The hub server, which lives in hub/, is a thin WebSocket relay that forwards messages between participants without reading or storing any content. The hub is intentionally minimal; the README describes its commit history as "incredibly boring" and notes that the server does not do much.
The project no longer operates a shared hub. Every deployment must run its own relay. The recommended approach is hub-worker/ in the repository root, a port of the relay logic to Cloudflare Workers and Durable Objects. The README states it runs on Cloudflare's free plan. An important constraint follows from the relay's transport: if TogetherJS is embedded on an HTTPS page, the hub must be accessible over WSS (WebSocket Secure). The Cloudflare Workers port handles this automatically because Workers always run behind HTTPS.
Installing Dependencies and Building the Library
TogetherJS uses LESS for its stylesheets and Grunt for the build process. The first step is cloning the repository:
$ git clone git://github.com/mozilla/togetherjs.git
$ cd togetherjsWith Node.js installed, add the project dependencies and install the Grunt command-line interface:
$ npm install
$ npm install -g grunt-cliThe npm install command pulls in all development dependencies, including the LESS compiler, the RequireJS optimizer, and the CSSlint runner. The grunt-cli package provides the grunt command globally. To build the complete togetherjs.com site into the build/ directory and start a local web server on port 8080:
$ grunt build buildsite --no-hardlink$ node devserver.jsDuring active development, the watch task rebuilds changed files when the filesystem reports changes:
$ grunt devwatchBy default, devwatch creates hard links from togetherjs/ into build/ so that edits appear without a full rebuild. The --no-hardlink flag disables this for filesystems that do not support hard links.
Generating a Static Bundle for Embedding on Your Site
When the goal is to embed TogetherJS on a specific application rather than run the full togetherjs.com site, a targeted static build is the correct approach. The Grunt build task accepts flags that configure the bundle:
$ grunt build --base-url https://myapp.com --no-hardlink --dest static-myappThis places two entry-point files at static-myapp/togetherjs.js and static-myapp/togetherjs-min.js, with the remaining client assets in static-myapp/togetherjs/. The --base-url flag tells TogetherJS where its own assets are hosted, which is required because the client fetches sub-resources at runtime. Deploy these files to your server and include the togetherjs.js script tag on the page. To point a local build at a non-default hub, set the HUB_URL environment variable before running Grunt:
$ HUB_URL=http://localhost:8080 grunt devwatchThis approach lets developers test with a locally running hub before deploying to Cloudflare Workers.
Testing Strategy: Browser-Based Only, No Automated Runner
The test suite lives in togetherjs/tests/ and uses doctest.js, which encodes assertions as annotated JavaScript comments rather than a separate spec format. The tests fall into two categories: unit tests named test_*.js and functional tests named func_*.js. Running them requires an already-built TogetherJS site, a running local server, and a browser pointed at http://localhost:PORT/togetherjs/tests/. Links on that page lead to the individual test files.
The README acknowledges that there is no automated runner and notes that integrating Karma has not been done. This is a concrete limitation for contributors: verifying changes to the client requires a manual browser session rather than a single terminal command. There is also a "Manual testing" link in the test index that simulates multiple users without requiring a second browser, which is useful for checking basic functionality without setting up a full two-client session.
Where TogetherJS Falls Short
TogetherJS carries several constraints that narrow its applicability. The removal of the shared hub is the biggest infrastructure change since the Mozilla era: each project is responsible for deploying and operating its own relay. This adds cost and availability decisions that previously did not exist. The version in package.json is 0.4.0a, which signals that the API is not considered stable. Several dependencies in package.json reference versions from 2012 to 2013, including Express 3.0.6 and LESS 1.3.1, which may conflict with current Node.js toolchains.
TogetherJS also has a page-scope limitation: both participants must be on the same URL. It does not support multi-page sessions, so a wizard flow across several pages requires explicit session handoff code at each navigation. There is no mechanism for synchronizing content in rich text editors or code editors directly; it mirrors raw DOM events, which can produce unpredictable results in editors that manage their own virtualized document trees. The test infrastructure has no automated runner, which increases the friction of contributing and verifying changes.
TogetherJS versus Yjs: Two Different Collaboration Models
Yjs is a conflict-free replicated data type library that operates entirely in the browser and provides shared document abstractions such as text buffers, arrays, and maps. Where TogetherJS synchronizes DOM mutations and pointer events over a relay hub, Yjs operates on an abstract shared data model and leaves rendering to the application. Yjs integrates with CodeMirror, ProseMirror, Quill, and other editors through published bindings, and supports multiple network providers including WebRTC and WebSocket.
The practical difference is in how much application code the developer must write. TogetherJS is a drop-in that adds awareness to an existing HTML page without touching the page's data model; a few lines of configuration and a script tag are enough to get started. Yjs requires integrating a shared data type into the application at the model layer, which involves more upfront work but gives full control over what is synchronized and allows offline operation with automatic merge on reconnection. TogetherJS is the lower-effort path for existing pages; Yjs is the right approach when the application owns its data model and needs to support concurrent edits or offline scenarios.
Editorial conclusion
TogetherJS suits developers who want to add a lightweight collaboration layer to an existing HTML page without redesigning it around a shared data model. The installation overhead is moderate, but the hub requirement is real: every production deployment needs a relay server, and hub-worker/ on Cloudflare Workers is the only self-contained option the repository provides. Teams that need conflict resolution, offline support, or integration with a text editor should look at Yjs instead. Before committing, verify that your hosting environment can run the Cloudflare Workers runtime or that you have the capacity to operate a standalone Node.js hub process.
Frequently asked questions
Does TogetherJS require running a server to function?
Yes. The shared hub server that Mozilla once operated was shut down. Every deployment must run its own relay, either as the Node.js process in hub/server.js or as a Cloudflare Workers deployment using the hub-worker/ directory included in the repository.
Can TogetherJS work on pages served over HTTPS?
Yes, but the hub server must also be reachable over WSS (WebSocket Secure). The README states this explicitly and notes that the Cloudflare Workers port in hub-worker/ handles the HTTPS requirement automatically.
What license is TogetherJS released under?
TogetherJS is released under the Mozilla Public License 2.0 (MPL-2.0). The README points to the full license text at http://mozilla.org/MPL/2.0/.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/jsfiddle-togetherjs)