A modern, minimalist real-time chat application built with React, Socket.IO, and a beautiful frosted-glass UI inspired by Nothing OS design language.
- Real-time messaging - Instant message delivery using WebSocket
- Typing indicators - See when other users are typing
- User presence - Know when users join the chat room
- Frosted glass UI - Beautiful glassmorphism design with noise texture
- Monochrome aesthetic - Calm, minimal, premium look
- Responsive design - Works seamlessly on mobile and desktop
- Smooth animations - Fade-in effects for messages and interactions
- Custom scrollbar - Sleek, minimalist scrollbar styling
- Enter to send - Quick message sending with keyboard shortcut
- React 19 - Modern React with hooks
- Vite - Lightning-fast build tool (using Rolldown)
- Socket.IO Client - WebSocket client for real-time communication
- Tailwind CSS v4 - Utility-first CSS framework
- Custom CSS - Glassmorphism effects and animations
- Node.js - JavaScript runtime
- Express 5 - Web framework
- Socket.IO - WebSocket server for real-time events
- HTTP Server - Built-in Node.js HTTP server
websocket/
βββ backend/
β βββ server.js # Socket.IO server
β βββ package.json # Backend dependencies
β βββ .gitignore
βββ frontend/
β βββ src/
β β βββ App.jsx # Main chat component
β β βββ ws..js # WebSocket connection manager
β β βββ main.jsx # React entry point
β β βββ index.css # Global styles & glassmorphism
β βββ public/
β β βββ pic11.png # Login screen
β β βββ pic12.png # Chat interface
β β βββ pic13.png # Active conversation
β βββ package.json # Frontend dependencies
β βββ vite.config.js # Vite configuration
β βββ index.html
βββ README.md
- Node.js (v18 or higher)
- npm or yarn
- Clone the repository
git clone https://github.com/ksamrat224/Hush.git
cd chat- Install backend dependencies
cd backend
npm install- Install frontend dependencies
cd ../frontend
npm install- Start the backend server
cd backend
node server.jsServer will run on http://localhost:4600
- Start the frontend development server (in a new terminal)
cd frontend
npm run devFrontend will run on http://localhost:5173
- Open multiple browser tabs to test real-time messaging between users
- Background:
#f5f5f5with subtle noise texture - Glass surfaces:
rgba(255, 255, 255, 0.7)with backdrop blur - Text primary:
black/70-80 - Text secondary:
black/30-40 - Borders:
black/5-20(ultra-subtle) - Message bubbles (sender):
black/90 - Message bubbles (receiver): Frosted glass with
white/50
- Body: System sans-serif (clean, minimal)
- Timestamps: JetBrains Mono (monospace, dot-matrix feel)
- Weights: 400-600 for calm aesthetic
- Frosted glass card with
backdrop-blur(20px) - Circular icon container
- Minimal border styling
- Smooth enter animation
- Header: Circular avatar with online status dot, typing indicators
- Messages: Distinct bubble styles for sender vs receiver
- Input: Floating frosted glass container with circular send button
- Scrollbar: Custom 4px slim scrollbar
The app uses a singleton pattern for WebSocket connections to prevent duplicate connections:
// ws..js
let socket = null;
export function connectWS() {
if (!socket) {
socket = io("http://localhost:4600");
}
return socket;
}joinRoom- User joins the chat roomchatMessage- Send/receive messagestyping- Broadcast typing statusstopTyping- Clear typing statusroomNotice- User presence notifications
- User types message and clicks Send or presses Enter
- Message is added to local state immediately (optimistic update)
- Message is emitted to Socket.IO server
- Server broadcasts to all other users in the room
- Receivers get the message and display it with fade-in animation
- Singleton WebSocket: Prevents duplicate connections in React StrictMode
- Named event handlers: Proper cleanup of Socket.IO listeners
- Optimistic updates: Messages appear instantly for sender
- Debounced typing: Typing indicator stops after 1 second of inactivity
- Room-based chat: All users join a single "group" room
- Mobile-first approach
- User badge hidden on small screens
- Message width adapts (85% mobile, 70% desktop)
- Touch-friendly button sizing
- Fluid typography and spacing
- Fade-in: New messages animate in from bottom (0.4s)
- Pulsing dots: Typing indicator with staggered animation
- Active scale: Buttons scale down to 0.98 on press
- Border transitions: Smooth focus states (200ms)
- Backdrop blur: Real-time frosted glass effect
Problem: Receivers were getting messages twice.
Cause: Event listeners were registered inside socket.on("connect") callback, causing multiple registrations on reconnection.
Solution:
- Moved listeners outside connect callback
- Used named handler functions for proper cleanup
- Ensured
socket.off()removes the exact listener
This project is open source and available under the MIT License.
Samrat Karki
- GitHub: @ksamrat224
- Design inspired by Nothing OS
- Built with modern web technologies
- Glassmorphism UI trend
Built with β€οΈ using React and Socket.IO


