A real-time collaborative survey editing system built with Survey Creator by SurveyJS. Multiple users can edit the same survey or form simultaneously, similar to Google Docs for document editing.
- Frontend – React + SurveyJS Creator (
survey-core,survey-creator-core,survey-creator-react) - Backend – Node.js + Express + WebSocket
- Storage – In-memory sessions (MVP, no persistence or auth)
- Users join or create a session via a session ID.
- Each session stores a Survey Creator model on the server in memory.
- Every edit in the creator is captured as a serialized change message.
- Changes are sent to the server over WebSocket and broadcast to other clients.
- Receiving clients apply updates to their local Survey Creator instance.
- Temporary suppression of local change listeners prevents update loops.
- Ordering is server-driven (last-write-wins at message level).
- Express serves the API and WebSocket endpoint.
- In development, the client is served via Vite middleware on the same port.
- In production, static assets are served from the built client bundle.
- The client listens to
creator.undoRedoController.undoRedoManager.onSerializedChanges. - Each change (property update, array mutation, undo, redo) is serialized into an
ISyncMessageand sent to the server. - The server applies the message to the session's in-memory
SurveyModel, ensuring new clients receive the latest state. - The server then broadcasts the message to all other clients in the same session.
- Each client applies incoming messages via
manager.applySerialized(message). - During application, local change listeners are temporarily disabled to prevent echoing remote updates back to the server.
npm install
npm run devThe application is available at http://localhost:8080. The server hosts the React client through embedded Vite middleware on the same port.
Open the app to create a session, then copy the invite link to collaborate in another tab.
A session ID can also be supplied directly in the URL path (/<sessionId>)—the client will join that session instead of creating a new one.
| Variable | Default | Description |
|---|---|---|
PORT |
8080 |
HTTP + WebSocket port |
NODE_ENV |
development |
Enables production mode when set to production (disables Vite middleware) |
CLIENT_DIST |
packages/client/dist |
Directory containing the production client build |
EMPTY_SESSION_TTL_MS |
1800000 (30 min) |
Time before an empty session is garbage-collected |
npm run build
npm startnpm run build compiles the server and builds the client application. npm start serves the production build on http://localhost:8080.
In production mode the server serves the static client bundle from packages/client/dist (override with CLIENT_DIST) and does not load Vite.
| Method | Path | Description |
|---|---|---|
| POST | /api/sessions |
Create a session |
| GET | /api/sessions/:id |
Fetch session state |
| GET | /health |
Health check |
| WS | /ws/sessions/:id |
Collaboration channel |
packages/protocol/index.d.ts— Shared wire protocol typespackages/server/src/index.ts— HTTP + WebSocket serverpackages/client/src/CollaborativeCreator.tsx— Survey Creator embedding and session handlingpackages/client/src/collab-client.ts— Client-side sync logic
- In-memory sessions only
- No authentication
- No persistence
- No presence or cursor tracking