← Back to Projects
LiveCollab

LiveCollab

Shared Kanban state across all connected clients — no polling, no refresh.

Live Code

Overview

Board operations — card moves, column reorders, member presence — propagate via Socket.IO events scoped per workspace room. Drag-and-drop is optimistically applied locally on the originating client and reconciled against the server's authoritative state on broadcast; other clients update silently without re-fetch. Workspace access is enforced at socket handshake: JWT is verified and membership is checked against MongoDB before any room join is admitted. Zustand manages local board state with selector-based subscriptions to prevent unnecessary re-renders on unrelated updates.

Key Features

  • Bidirectional Socket.IO events for card movement, creation, deletion, and column reorder — all reflected live across sessions
  • Optimistic local state with server reconciliation on conflict — last server-confirmed state wins
  • Live presence indicators — per-user status visible to all workspace members in real time
  • Invite-code workspace onboarding — no email verification required to join a team
  • Timestamped activity log persisted to MongoDB — full audit trail of board actions
  • JWT auth at socket handshake level — room access is gated before any event is processed

Tech Stack

Frontend: React 18, Vite, Tailwind CSS, Zustand, React Query, @dnd-kit

Backend: Node.js, Express, Socket.IO

Database: MongoDB, Mongoose

Auth: JWT, bcrypt

Challenges

  • Race conditions on simultaneous drag events from multiple clients targeting the same card position
  • Socket room authentication — ensuring users can only emit and receive events for workspaces they belong to
  • Zustand store hydration on socket reconnect — stale local state after a dropped connection

Solutions

  • Server processes drag events sequentially per workspace; broadcasts the authoritative position to all clients including the originator, who discards their optimistic state if it differs
  • JWT is verified on every socket handshake; room join is gated behind a workspace membership check against MongoDB before the socket is admitted to the room
  • On reconnect, the client fetches a full board snapshot via REST then re-subscribes to socket events — socket events only handle deltas after initial hydration

Future Improvements

  • Card assignment with per-user task filtering across workspaces
  • Rich-text card descriptions with inline comment threads and @mentions
  • Redis pub/sub adapter for horizontal Socket.IO scaling across multiple Node instances