michan
A shared video room with real-time chat, custom emotes, and synchronized playback across typed WebSocket connections.
A multi-package TypeScript monorepo enabling groups to watch YouTube videos together in real-time, with synchronized playback, message editing/deletion, emote uploads, debug log sharing, and guest or registered auth. End-to-end type safety across Express backend, React client, and shared schema definitions.
- TypeScript
- React 19
- Express.js
- WebSocket (ws)
- MySQL 8
- JWT
- bcrypt
- sharp
- Vite
- Tailwind CSS
- React Router
- Node.js
michan is a collaborative video room where users can watch YouTube videos together and chat in real time. The system synchronizes playback across all participants via WebSocket, handles video queue management, and tracks playback position with seek authority delegated to the user who loaded the current video. Built as a three-package TypeScript monorepo: a shared schema package ensures type safety across the Express.js backend and React 19 client; the server manages MySQL persistence, JWT auth (supporting both guest and registered users), connection pooling, and real-time event broadcasting; the client provides a responsive UI with Tailwind CSS, video player controls, chat sidebar with emote support, and settings persistence.
The architecture uses a strict type-safe protocol over WebSocket envelopes, where each client command carries a sequence number for reliable request–response pairing and broadcasts are tagged with null ACKs. Emotes are uploaded as images and auto-resized to three variants (32x32, 64x64, 128x128) using sharp; users can trigger emote autocomplete inline. Message editing and deletion are tracked with flags in the database and propagated to all room participants. The application includes a debug log viewer with optional log sharing—users can broadcast client-side logs (categorized as ws, yt, state, or ui) to other users in their room.
The database schema spans users (with optional password hashing), rooms, messages with image attachments, queue items, emotes scoped per room, and user settings stored as JSON. Docker Compose brings up MySQL 8 and phpMyAdmin for development. The monorepo uses npm workspaces and a shared tsconfig base for build consistency; root scripts orchestrate concurrent dev mode across server and client, and a single typecheck command validates the entire project.
- Multi-package TypeScript monorepo with shared schema ensuring end-to-end type safety across Express backend and React client
- Real-time WebSocket protocol with sequence-numbered request–response pairs and per-room broadcast events for synchronized video playback and chat
- Guest and registered user authentication via JWT, with optional password registration and bcrypt hashing
- Custom emote uploads with automatic image resizing to three display variants (32x32, 64x64, 128x128) using sharp
- Message editing and deletion with soft-delete flags propagated to all clients; user typing indicators and debug log sharing for collaborative troubleshooting