2026-01-12 00:16:55 -08:00
2026-01-12 00:16:55 -08:00
2026-01-12 00:16:55 -08:00
2025-12-29 16:29:24 -08:00
2025-12-29 16:29:24 -08:00
2025-12-29 16:29:24 -08:00

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

  1. 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
  1. Start infrastructure
docker-compose up -d
  1. Run backend
cd backend
go mod download
go run cmd/server/main.go
# Server runs on http://localhost:8080
  1. 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 login
  • POST /api/auth/github - GitHub OAuth login
  • GET /api/auth/me - Get current user
  • POST /api/auth/logout - Logout
  • GET /api/documents - List all documents
  • POST /api/documents - Create document
  • GET /api/documents/:id - Get document
  • PUT /api/documents/:id/state - Update Yjs state
  • DELETE /api/documents/:id - Delete document
  • POST /api/documents/:id/shares - Share with user
  • POST /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

  1. User edits → Yjs generates binary update
  2. Update sent via WebSocket to backend
  3. Backend broadcasts to all clients in room
  4. Each client's Yjs applies and merges update
  5. IndexedDB persists state locally
  6. 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

  • Yjs - CRDT framework
  • TipTap - Collaborative editor
  • Gin - Go web framework
Description
No description provided
Readme 377 KiB
Languages
Go 53.5%
TypeScript 26.1%
CSS 10.5%
JavaScript 5.8%
PLpgSQL 3.3%
Other 0.8%