Notes of a collaborative webapp

XERUS - Unmet Needs of a WorldCongress

Creation of a real-time collaborative client-server gamification application. One of the requirements is “accessibility”, so a browser-based app was a given.

Objectives and the TechStack

A simple Client-Server Architecture, collaborative Application. NestJS and socketio on the Server and React Client. Websockets for Real-Time-Sharing and in the future a Database to persist Data and User-Auth.

Explorations + Decisions

It is a private mono repository and server and client is handled via yarn workspaces.

Some History

I’ve also considered WASM/emscripten or building an app with PlayCanvas, Unreal engine or OF, maybe for my next multiplayer side project.


I tried not to blindly choose any mainstream libraries, but React with Typescript is a solid choice for reasons (VS code/language server supports autocomplete on types, which is really helpful to get things done reliably). A frontend router (location[5] or wouter) and native websockets and state management (Zustand).

While there are many possibilities with 3D in CSS, I didn’t want to miss the opportunity to use WebGL and the recently (React 16) introduced Reconciliation alogrithm “React-Fiber”, which is based on a somewhat overused Linked List, but seems to work great with R3F (React-Three-Fiber), which allows to use React’s scheduling capabilities with ThreeJS [6].


A small Typescript NestJS Server with SocketIO as WebSocket Gateway and express as HTTP Backend. First I tried the Ws-library, but then I switched to SocketIO.

Collaborative Data

The standard solutions are OT (Operational Transform) or CRDT (convergent or commutative replicated data type).

  • OT: Operations are sent over the wire and concurrent operations are transformed once they are received.
  • CvRDTs (convergent replicated data types): State based. Its full local state is sent and is merged with the state of a copy (or optimized, Delta Mutations).
  • CmRDTs (commutative replicated data types) operation based, for example only “+b” is transmitted and applied locally (a+b has the same result as b+a and is therfore commutative).

While evaluating industry standards, I came up with a simple solution that works purposefully for an MVP: Broadcast the full state to all clients. This pragmatic approach is of course only a crutch to be able to test a proof of concept on students of the actual target of the application.


Release Value Status
enphi v0.1 very basic Collab DONE
v0.2 Persistence, DB? WIP

The repository was private and deployed from github to digitalocean and used a terminated mongodb-cluster:

Written on February 7, 2022
[ websockets  typescript  ]