SuperDoc

Running SuperDoc Real-Time Collaboration in Production

Running SuperDoc Real-Time Collaboration in Production

Getting two browsers editing the same Word document in a local demo takes an afternoon. Running real-time collaborative DOCX editing for paying customers is a different project. It involves authentication, room authorisation, durable storage, recovery from failures, and an audit story your customers’ security teams will accept.

This is the operations guide that introductory SuperDoc material does not cover. SuperDoc, the DOCX editor we introduced in What Is SuperDoc?, uses the Yjs model for collaboration and leaves the server side to you. Its documentation is candid about what that means: “The minimal server deliberately has no authentication or durable storage.” This article sets out what you need to add, from SuperDoc’s own guidance, checked on 9 October 2026.

SuperDoc’s editor code is open source under AGPLv3, while its DOCX Engine is a separately licensed, proprietary component. SuperDoc ships frequently, and its documentation labels the collaboration configuration used below as a preview API. Check the status for the release you deploy. The architecture recommendations are ours.

The Architecture in One Paragraph

The browser editor holds a local copy of the shared document state and synchronises it through a provider to a collaboration server. In SuperDoc’s words, “SuperDoc owns the browser connection and local shared state”. You pass connection settings, not your own Yjs objects. The server relays updates between participants and stores the room’s state, but it does not handle Word files: “The Hocuspocus server transports and stores shared state; it does not import the DOCX itself.” Your application owns everything else: who may join which room, where state is stored, how DOCX snapshots are produced and versioned, and how failures are handled.

Choosing a Provider

“Hocuspocus is the local example’s default, not a requirement.” SuperDoc supports three provider families, configured through the document’s collaboration setting. A fourth providerType, 'extension', runs your own adapter code, which must still speak one of the same three protocols. The built-in types are:

providerType Room and connection Authentication
'hocuspocus' documentId and serverUrl (or url) token or string params
'y-websocket' documentId and serverUrl (or url) String params forwarded to your server
'liveblocks' documentId or roomId Exactly one of authEndpoint or publicApiKey

For Liveblocks, SuperDoc advises: “use an authenticated endpoint when access must be checked per room; a public key does not provide that check.”

Our view of the choice:

  • Hocuspocus is the documented path, with the most worked examples, including authentication and storage hooks. It is the sensible default if you will run your own server.
  • y-websocket suits teams already operating a Yjs infrastructure.
  • Liveblocks moves the server operation to that provider, in exchange for a third-party dependency in your data flow. That has implications for data location and your security review.

SuperDoc does not document a SuperDoc-hosted collaboration service. Its website states that its “collaboration infrastructure can also be self-hosted.”

Connecting the Editor

SuperDoc’s documented client configuration for Hocuspocus, with a token function for authentication:

import { SuperDoc, type DocumentCollaborationConfig } from 'superdoc';

const collaboration = {
  providerType: 'hocuspocus',
  serverUrl: 'wss://collab.example.com',
  documentId: 'contract-42',
  token: () => getAccessToken(),
  roomMode: 'join',
} satisfies DocumentCollaborationConfig;

new SuperDoc({ selector: '#editor', document: { url: '/contract.docx', collaboration } });

“token can be a string or a function. SuperDoc calls the function for every connection, including reconnects, so it can return a fresh token.” The token is separate from the user setting, “which supplies display identity for the editor”. The synchronisation timeout, syncTimeoutMs, “defaults to 30,000 milliseconds”.

Hardening the Server

SuperDoc’s guidance lists what a production server needs: “Before deployment, authenticate the WebSocket connection, authorize each room, persist room updates, set connection and document limits, and define backup and recovery behavior in the server layer.” And the principle behind it: “Your server owns authorization; browser controls and display identity do not enforce it.”

Authenticate and authorise every room

SuperDoc’s room-access example uses Hocuspocus’s onAuthenticate hook to map a token to a session and check the requested room:

export async function authenticateRoom({ token, documentName }) {
  const session = sessions.get(token);
  if (!session || !session.rooms.includes(documentName)) {
    throw new Error('Access denied');
  }
  return { userId: session.userId };
}

In production, sessions is your identity and permissions service, not an in-memory map. Three details from the documentation are easy to get wrong:

  • Room names change on the server. “documentId: 'contract-42' reaches Hocuspocus as sd2/v2.1/contract-42. Update any server hooks that authorize or store rooms by name.” And: “do not authorize by matching only a suffix.”
  • A room ID is not a credential. “A room ID identifies it; it does not grant access. A cursor’s display name is not proof of identity.”
  • Connection-time checks are not the whole story. “Rechecking access after token expiry or permission changes needs an explicit server policy, not just this initial connection check.” If a user’s access is revoked mid-session, your server has to act.

Also protect the files around the room: “Protect the source DOCX download and export storage too; room authorization does not secure separate file endpoints.” And outside development: “Never put production secrets in a VITE_ variable, source file, or URL. Use HTTPS and secure WebSockets outside local development.”

Handle rejection clearly in the client

SuperDoc reports collaboration failures with a reason, so the user sees something useful:

const onException = (failure) => {
  if ('collaborationReason' in failure) {
    switch (failure.collaborationReason) {
      case 'access-denied':
        console.error('Check your sign-in and permission to open this document.');
        break;
      case 'connection-failed':
      case 'sync-timeout':
        console.error('Could not connect. Check your connection and try again.');
        break;
    }
    return;
  }
  console.error(failure.error);
};

A recent release also added “getCollaborationConnectionState() and onCollaborationConnectionChange” to “Track room outages and recovery”. Use them to tell users when their edits are not reaching the server.

Saving the DOCX Does Not Save the Room

This is the most important operational point in SuperDoc’s collaboration documentation:

“Saving only DOCX snapshots does not persist the Yjs room. Saving room state does not automatically write a DOCX to your file storage.”

There are two different things to store:

What to keep What it is for
Binary Yjs room state “Reopening the same collaborative document, including its edits.”
Exported DOCX “Downloading, sharing, or keeping a file snapshot.”
Awareness “Showing who is here now. It is temporary, not saved room content.”

SuperDoc’s storage example uses Hocuspocus’s onLoadDocument and onStoreDocument hooks, with applyUpdate and encodeStateAsUpdate from Yjs. In outline:

async onLoadDocument({ document, documentName }) {
  // Missing state means a new room; anything else unreadable must fail.
  applyUpdate(document, await loadRoomState(documentName));
},
async onStoreDocument({ document, documentName }) {
  await saveRoomState(documentName, encodeStateAsUpdate(document));
},

The rules that matter:

  • “Store binary data, not Y.Doc.toJSON().”
  • “Only a missing file is treated as a new room. Unreadable or corrupt state must fail rather than silently replace saved content with the original DOCX.”
  • “onCollaborationReady means the editor has synchronized and is ready. It is not a storage acknowledgment. Show ‘Saved’ only when your storage flow confirms the changes it committed.”
  • “Hocuspocus schedules storage writes; a keystroke does not mean the room has been saved yet.”

SuperDoc’s own example writes to local files and states that it “does not provide multi-server coordination, backups, or a power-loss durability guarantee. Use your provider’s storage integration for your database or object store, with authorization and a recovery policy.”

Creating Rooms Without Duplicates

When a document is first opened for collaboration, its DOCX content must be loaded into a new room exactly once. SuperDoc explains what goes wrong otherwise: “If two workers open the same new room with roomMode: 'create', both can start importing the DOCX before either sees the other’s work. The room can then contain duplicated content.” And “a WebSocket connection does not reserve a room for one creator.”

The guidance is to “Choose one initialization path, not competing browser and backend creators”. create “fails if the room already exists”, and join “does not initialize a missing room from the supplied file.” For automatic recovery, SuperDoc describes a server-side record of each document’s “source revision, current room ID, initialization state, and attempt number”, used to:

  1. reserve one initialiser per document and source revision;
  2. check the current attempt when admitting every incoming document write;
  3. allow a replacement attempt to resume only when it is safe, and otherwise start a new, unpublished room or recover the authoritative state;
  4. publish the document-to-room mapping, and admit editors, only after the completed room is validated and durable storage is confirmed.

If you run more than one collaboration server instance, “they need one authoritative room owner or a shared atomic write-admission boundary.”

Attribution and Audit

Customers will ask who changed what. Be precise about what each mechanism tells you.

  • Display identity is not proof. “Treat names and emails supplied in user as display identity unless they came from an authenticated application session.”
  • Presence is not an audit log. The documentation says not to “use presence as an audit log or a saved indicator.”
  • Tracked changes carry authors. In suggesting mode, edits become tracked changes attributed to the configured user. When that identity comes from your authenticated session, this is a durable, in-document record.
  • Edit attribution is new. A September 2026 release added “Edit attribution — Yjs edits tagged with human vs. programmatic origin for server-side revision tracking and auto-save logic.” At the time of writing, SuperDoc’s public documentation does not explain how a server reads this information. Our advice is not to build an audit trail on it until it is documented.

Our recommendation is to build the audit trail on things your server controls: authenticated connections, room admissions, storage commits and version creation, alongside tracked changes in the document.

Versions in a Collaborative World

Version history remains the application’s job: “SuperDoc exports and opens the files; your application decides when to create a version and where to store it.” In collaboration there is an extra hazard. SuperDoc warns that its restore helpers restore “a standalone Editor, not a live collaboration room”, and that “In collaboration, replacing the file can replace shared content for everyone.” Design restore as a deliberate, server-coordinated operation.

The Trade-Off: Control Versus Operational Cost

This section is our analysis. With Microsoft’s embedding options, someone else runs co-authoring. SharePoint Embedded offers “Real-time co-authoring in Office for the web and Office desktop clients”, operated by Microsoft. With a CSPP WOPI integration, Microsoft’s editors handle co-authoring against your WOPI host.

With SuperDoc, you run it. That is the control many customers want, especially those who need documents and edit traffic kept within their own infrastructure. It is also an operational commitment: a stateful real-time service to run, scale, monitor, back up and secure. Neither choice is wrong, but the operating cost belongs in the decision from the start. We compared the approaches in How Does SuperDoc v2 Compare to CSPP WOPI? and Shipping Co-Authoring in Your SaaS: What SharePoint Embedded Gives You Out of the Box.

A Production Checklist

  1. Choose a provider deliberately. Use an authenticated endpoint for Liveblocks.
  2. Authenticate every WebSocket connection with a fresh token.
  3. Authorise every room by its full server-side name against your permissions model.
  4. Define what happens when access is revoked mid-session.
  5. Persist binary Yjs room state durably. Fail on corrupt state, never reseed over it.
  6. Show “Saved” only after a storage commit.
  7. Initialise each room exactly once, with a server-side record of attempts.
  8. Coordinate room ownership across server instances.
  9. Set connection and document limits, and test backup and restore.
  10. Protect DOCX download and export endpoints separately.
  11. Build audit on server-side events and authenticated tracked changes.

How McKenna Consultants Can Help

McKenna Consultants builds collaborative document experiences, from Microsoft’s co-authoring through WOPI and SharePoint Embedded to self-hosted editors such as SuperDoc. We can design and build your collaboration server, its authorisation and storage, and the operational monitoring around it. We can also help you decide whether you should be running collaboration at all.

Contact us to discuss collaborative editing in your product, or read more about our systems integration services.

Sources

All sources checked on 9 October 2026.

Have a question about this topic?

Our team would be happy to discuss this further with you.