Real-time collaborative code editor with WebSocket sync, live cursors, and autocomplete. Built for pair programming and team collaboration.
- Real-time Sync - Multiple users edit simultaneously with instant updates
- Live Cursors - See where teammates are typing in real-time
- Autocomplete - Context-aware code suggestions (Python)
- No Sign-up - Create room and start coding immediately
- Fast - Sub-50ms latency via WebSockets
- Scalable - Redis pub/sub for horizontal scaling
Frontend: Next.js 15 • React 19 • TypeScript • Monaco Editor • shadcn/ui • Tailwind
Backend: FastAPI • Python 3.12 • Redis • WebSockets • uv
Infrastructure: Docker • Docker Compose
# Clone repo
git clone https://github.com/grimmy-dev/coed.git
cd coed
# Start all services
docker-compose up --build
# Access app
# Frontend: http://localhost:3000
# Backend: http://localhost:8000/docs
# Redis: localhost:63791. Start Redis
docker run -d -p 6379:6379 redis:7-alpine2. Backend
cd backend
pip install uv
uv pip install -r pyproject.toml
uv run main.py3. Frontend
cd frontend
pnpm install
pnpm dev- Create Room → Click "Create New Room"
- Share Link → Copy room URL to clipboard
- Join Room → Teammates enter room code
- Code Together → Edit with live sync
- See Cursors → View teammate positions
- Autocomplete → Pause typing for suggestions
.
├── backend/ # FastAPI server
│ ├── config/ # Redis & settings
│ ├── models/ # Pydantic schemas
│ ├── routers/ # API endpoints
│ ├── services/ # Business logic
│ └── BACKEND.md # Backend docs
│
├── frontend/ # Next.js app
│ ├── app/ # Pages & routes
│ ├── components/ # React components
│ ├── hooks/ # WebSocket & autocomplete
│ ├── lib/ # API client & utils
│ └── FRONTEND.md # Frontend docs
│
└── docker-compose.yml # Orchestration
POST /rooms # Create new room
GET /rooms/{id}/exists # Check room exists
POST /rooms/autocomplete # Get code suggestions
GET /health # Health checkWS /ws/{room_id}
Client → Server:
code_update- User edited codecursor_move- User moved cursor
Server → Client:
init- Initial room statecode_update- Code changedcursor_move- Cursor moveduser_joined- User connecteduser_left- User disconnected
Create .env in root:
# Backend
REDIS_URL=redis://localhost:6379
CORS_ORIGINS=http://localhost:3000
ROOM_TTL_SECONDS=7200
# Frontend
NEXT_PUBLIC_URL=http://localhost:3000
NEXT_PUBLIC_API_URL=http://localhost:8000
NEXT_PUBLIC_WS_URL=ws://localhost:8000- Debounced updates (300ms) reduce network traffic
- Throttled cursors (100ms) prevent spam
- Auto-reconnect with exponential backoff
- Last-write-wins conflict resolution
- Calculates positions from Monaco measurements
- Adapts to font size and zoom changes
- Color-coded per user (8 colors)
- Smooth CSS transitions
- Rule-based pattern matching (no ML)
- Triggers:
def,class,for,import, etc. - 600ms debounce to avoid spam
- Context-aware based on cursor position
- Redis pub/sub for horizontal scaling
- Multiple backend instances share state
- Stateless WebSocket connections
- Auto-expiring rooms (2-hour TTL)
| Metric | Target |
|---|---|
| Code sync latency | < 50ms (local) |
| Cursor updates | 10/sec max |
| Autocomplete | < 100ms |
| Room creation | < 10ms |
| WebSocket connect | < 500ms |
- No persistence - Code lost when all users leave
- No CRDT - Simple last-write-wins
- Python only - Autocomplete limited (extensible)
- Single room - One room per user at a time
WebSocket won't connect:
# Check backend is running
curl http://localhost:8000/health
# Check Redis
redis-cli ping
# Verify environment variables
echo $NEXT_PUBLIC_WS_URLRoom not found:
- Rooms expire after 2 hours (TTL)
- Create a new room
Autocomplete not working:
# Check backend logs
docker-compose logs backend
# Test endpoint
curl -X POST http://localhost:8000/rooms/autocomplete \
-H "Content-Type: application/json" \
-d '{"code": "def ", "cursor_position": 4, "language": "python"}'Cursors misaligned:
- Monaco measurements calculated dynamically
- Check browser console for errors
- Refresh page to recalculate
# Build and start
docker-compose up --build
# Start in background
docker-compose up -d
# View logs
docker-compose logs -f
# Restart service
docker-compose restart backend
# Stop and remove
docker-compose down
# Clean everything
docker-compose down -vBackend:
cd backend
uvicorn main:app --reload
# Docs: http://localhost:8000/docsFrontend:
cd frontend
pnpm dev
# App: http://localhost:3000Redis CLI:
docker exec -it redis redis-cli
> KEYS room:*
> GET room:abc123:code- Backend Documentation - API, services, Redis structure
- Frontend Documentation - Components, hooks, WebSocket
Built with Next.js • FastAPI • Redis • WebSockets


