A high-performance, room-based collaborative code editor built with a Go (WebSocket) backend and a React (Monaco Editor) frontend.
- Real-Time Synchronization: Instantly sync code changes across multiple clients using low-latency WebSockets.
- Room Isolation: Support for multiple concurrent documents ("rooms"). Users in the same room collaborate; users in different rooms are isolated.
- Monaco Editor Integration: Uses the same engine that powers VS Code for a premium editing experience (syntax highlighting, intellisense, etc.).
- Infinite Loop Prevention: Smart state management prevents "echo-back" loops during broadcasts.
- Cursor-Safe Updates: Remote changes are applied without moving the local user's cursor or destroying undo history.
- Modern UI: Polished dark-themed interface with status indicators and a theme toggle.
- Language: Go (Golang)
- Communications: WebSockets via
gorilla/websocket - Architecture: Hub/Client pattern with goroutines and channels (Mutex-free hot path)
- Framework: React (Vite)
- Editor: Monaco Editor (
@monaco-editor/react) - Styling: Vanilla CSS
cd backend
go run .The server will start on http://localhost:8081.
cd frontend
npm install
npm run devThe editor will be available at http://localhost:5173.
.
├── backend/ # Go WebSocket Server
│ ├── main.go # Entry point & HTTP routes
│ ├── hub.go # Room-based broadcast logic
│ ├── client.go # WebSocket connection management
│ ├── room.go # Room management (thread-safe)
│ └── static/ # Minimal HTML test client
└── frontend/ # React + Vite Application
├── src/
│ ├── App.jsx # Main Editor UI
│ ├── hooks/ # Custom WebSocket hooks
│ └── assets/ # Styles and images
└── package.json # Frontend dependencies
- Client types in Monaco Editor.
- React sends a JSON message (
type: "code_change") via WebSocket. - Go Backend receives message in a
readPumpgoroutine. - Hub broadcasts the message to all other clients in the same
roomId. - Other Clients receive the message in their
writePumpgoroutine. - React applies the update to Monaco via
executeEditsto preserve local cursor/state.
- Write Deadlines: Prevents slow clients from blocking the server.
- Ping/Pong: Monitors connection health and cleans up "leaked" clients.
- Anti-Echo Ref: React uses an
isRemoteUpdateref to distinguish between local typing and remote sync.
- Open
http://localhost:5173in Browser Tab A. - Open the same URL in Browser Tab B.
- Ensure both are joined to the same Room (e.g.,
doc-1). - Type in Tab A — watch Tab B update in real-time!