6b1ed8d11c39dfe8f052301cde24e73f172d682d
Real-Time Collaboration Platform
A full-stack real-time collaborative application supporting text editing and Kanban boards. Built with React, Go, Yjs CRDTs, and WebSockets.
Features
- Collaborative Text Editor: Real-time document editing with TipTap
- Collaborative Kanban Boards: Drag-and-drop task management
- User Authentication: OAuth2 login (Google, GitHub)
- Document Sharing: Share documents with users or via public links
- Offline Support: IndexedDB persistence for offline editing
- User Presence: Live cursors and user awareness
Tech Stack
Frontend: React 19, TypeScript, Vite, TipTap, Yjs, y-websocket, y-indexeddb Backend: Go 1.25, Gin, Gorilla WebSocket, PostgreSQL 16 Infrastructure: Docker Compose
Quick Start
Prerequisites
- Node.js 18+, npm
- Go 1.25+
- Docker & Docker Compose
Setup
- Clone and configure environment
git clone <repo-url>
cd realtime-collab
# Setup environment files
cp .env.example .env
cp backend/.env.example backend/.env
# Edit .env files with your configuration
# Minimum required: DATABASE_URL, JWT_SECRET
- Start infrastructure
docker-compose up -d
- Run backend
cd backend
go mod download
go run cmd/server/main.go
# Server runs on http://localhost:8080
- Run frontend
cd frontend
npm install
npm run dev
# App runs on http://localhost:5173
Architecture
System Overview
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Browser │◄────────►│ Go Backend │◄────────►│ PostgreSQL │
│ │ │ │ │ │
│ React + Yjs │ WS+HTTP │ Gin + Hub │ SQL │ Documents │
│ TipTap │ │ WebSocket │ │ Users │
│ IndexedDB │ │ REST API │ │ Sessions │
└─────────────┘ └──────────────┘ └─────────────┘
Real-Time Collaboration Flow
Client A Backend Hub Client B
│ │ │
│──1. Edit document──────────►│ │
│ (Yjs binary update) │ │
│ │──2. Broadcast update────►│
│ │ │
│ │◄─3. Edit document────────│
│◄─4. Broadcast update───────│ │
│ │ │
▼ ▼ ▼
[Apply CRDT merge] [Relay only] [Apply CRDT merge]
Authentication Flow
User OAuth Provider Backend Database
│ │ │ │
│──1. Click login───────►│ │ │
│◄─2. Auth page──────────│ │ │
│──3. Approve───────────►│ │ │
│ │──4. Callback──────►│ │
│ │ │──5. Create user───►│
│ │ │◄──────────────────│
│◄─6. JWT token + cookie─┤◄──────────────────│ │
Project Structure
realtime-collab/
├── backend/
│ ├── cmd/server/ # Entry point
│ ├── internal/
│ │ ├── auth/ # JWT & OAuth middleware
│ │ ├── handlers/ # HTTP/WebSocket handlers
│ │ ├── hub/ # WebSocket hub & rooms
│ │ ├── models/ # Domain models
│ │ └── store/ # PostgreSQL data layer
│ └── scripts/init.sql # Database schema
├── frontend/
│ ├── src/
│ │ ├── api/ # REST API client
│ │ ├── components/ # React components
│ │ ├── hooks/ # Custom hooks
│ │ ├── lib/yjs.ts # Yjs setup
│ │ └── pages/ # Page components
└── docker-compose.yml # PostgreSQL & Redis
Key Endpoints
REST API
POST /api/auth/google- Google OAuth loginPOST /api/auth/github- GitHub OAuth loginGET /api/auth/me- Get current userPOST /api/auth/logout- LogoutGET /api/documents- List all documentsPOST /api/documents- Create documentGET /api/documents/:id- Get documentPUT /api/documents/:id/state- Update Yjs stateDELETE /api/documents/:id- Delete documentPOST /api/documents/:id/shares- Share with userPOST /api/documents/:id/share-link- Create public link
WebSocket
GET /ws/:roomId- Real-time sync endpoint
Environment Variables
Backend (.env)
PORT=8080
DATABASE_URL=postgres://user:pass@localhost:5432/collaboration?sslmode=disable
JWT_SECRET=your-secret-key-here
FRONTEND_URL=http://localhost:5173
ALLOWED_ORIGINS=http://localhost:5173,http://localhost:3000
# OAuth (optional)
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
Docker (.env in root)
POSTGRES_USER=collab
POSTGRES_PASSWORD=your-secure-password
POSTGRES_DB=collaboration
Development Commands
Backend
cd backend
go run cmd/server/main.go # Run server
go test ./... # Run tests
go test -v ./internal/handlers # Run handler tests
go build -o server cmd/server/main.go # Build binary
Frontend
cd frontend
npm run dev # Dev server
npm run build # Production build
npm run lint # Lint code
Database
docker-compose down -v # Reset database
docker-compose up -d # Start fresh
How It Works
CRDT-Based Collaboration
- Yjs provides Conflict-free Replicated Data Types (CRDTs)
- Multiple users edit simultaneously without conflicts
- Changes merge automatically, no manual conflict resolution
- Works offline, syncs when reconnected
Backend as Message Broker
- Backend doesn't understand Yjs data structure
- Simply broadcasts binary updates to all clients in a room
- All conflict resolution happens client-side via Yjs
- Rooms are isolated by document ID
Data Flow
- User edits → Yjs generates binary update
- Update sent via WebSocket to backend
- Backend broadcasts to all clients in room
- Each client's Yjs applies and merges update
- IndexedDB persists state locally
- Periodic backup to PostgreSQL (optional)
Testing
The backend uses testify/suite for organized testing:
go test ./internal/handlers # All handler tests
go test -v ./internal/handlers -run TestDocumentHandler # Specific suite
Database Schema
- documents: Document metadata and Yjs state (BYTEA)
- users: OAuth user profiles
- sessions: JWT tokens with expiration
- shares: User-to-user document sharing
- share_links: Public shareable links
License
MIT License
Acknowledgments
Description
Languages
Go
53.5%
TypeScript
26.1%
CSS
10.5%
JavaScript
5.8%
PLpgSQL
3.3%
Other
0.8%