Collaboration Without Streaming Pixels
Excalidraw’s collaboration path extends the same structured scene to several browsers without treating the canvas image as the shared object. This chapter traces the hosted application from room-link and key creation through encrypted live messages, image-file handling, per-element reconciliation, periodic full-scene synchronization, and encrypted persistence. The goal is to make two boundaries clear: what the observed code encrypts and exchanges, and what its deterministic conflict rules can or cannot decide about simultaneous edits.
A collaborative drawing is therefore not one giant bitmap moving between users. Clients exchange structured element records and render their own views locally. That preserves the scene model established earlier, but it also makes identity, versions, ordering, deletion, file status, and key handling operational requirements rather than abstract metadata.
A room link creates a client-side privacy boundary
When the hosted application starts a room, it generates a random room identifier and an encryption key. Both are placed in the collaboration URL’s hash. The hash is part of the browser location but is not sent to the server in the same way a query parameter normally would be. A user who receives the link can supply the room identifier for routing and the key needed to interpret the encrypted payloads. The application validates the shape of the link and the expected key form before using it.
This design makes the link more than an invitation. It carries the information a client needs to join the same cryptographic context. It also establishes a boundary between room routing and scene interpretation. The transport service needs to know which room to deliver a message to, but the client-side collaboration code serializes the update and encrypts it before emission. On receipt, the other client decrypts the payload before parsing the scene or presence message.
The observed encryption path uses AES-GCM through the browser’s Web Crypto API. For each encrypted payload, the client creates a fresh initialization vector, encrypts the bytes, and sends the ciphertext together with the IV. The receiver uses the room key and IV to authenticate and decrypt the data. The same family of helpers is used for live collaboration messages, room snapshots, share-link payloads, and image files, although the surrounding storage and metadata formats differ.
A simplified live message therefore has a clear sequence. The client turns an update object into JSON. It encodes the JSON as bytes. It encrypts those bytes with the room key and a fresh IV. The transport carries the encrypted buffer and IV. The receiving client decrypts, decodes, and dispatches the resulting message according to its type. The server in the middle can forward the payload without being the code that decides which rectangle moved or what text it contains in this observed path.
That statement needs a careful boundary. Encrypting scene payloads on the client is evidence about the implementation path, not a complete security audit. The browser must receive trustworthy client code. Keys must remain protected in the relevant threat model. Room membership, timing, network endpoints, and other metadata may remain visible to infrastructure even when message bodies are encrypted. Presence messages can also have different privacy consequences from scene content: a cursor, username, selected IDs, or idle state describes activity even if the transport wraps the serialized message in the same encryption routine.