Three contexts, one reusable component. Type a message and hit Enter to try it out. An incoming message will arrive in ~3 seconds.
Pass messages and onSend props to wire up real-time Socket.io.
The component handles rate limiting, scroll, unread badges, and typing indicators out of the box.