A real-time chat application built as a technical assessment using React, Node.js, Express, Socket.io, and SQLite.
The application supports instant messaging between connected users, persistent chat history, timestamps, username-based login, typing indicators, online-user status, and message delivered/read status.
- Send and receive messages in real time using Socket.io
- REST API for sending messages
- REST API for fetching chat history
- Previous messages persist after refreshing the application
- Message timestamps
- Real-time broadcasting to connected users
- Graceful Socket.io connection/disconnection handling
- API and Socket error handling
- Organized frontend and backend structure
- Responsive and user-friendly chat interface
- Username-based dummy authentication
- Online user count/status
- Typing indicator
- Message delivered status
- Message read status
- SQLite database for persistent message storage
- React
- Vite
- Socket.io Client
- Lucide React
- CSS
- Node.js
- Express
- Socket.io
- SQLite
- sqlite3
- CORS
- dotenv
realtime-chat-app/
│
├── frontend/
│ ├── src/
│ │ ├── components/
│ │ │ ├── ChatHeader.jsx
│ │ │ ├── MessageBubble.jsx
│ │ │ ├── MessageInput.jsx
│ │ │ └── UsernameModal.jsx
│ │ │
│ │ ├── services/
│ │ │ ├── api.js
│ │ │ └── socket.js
│ │ │
│ │ ├── App.jsx
│ │ ├── App.css
│ │ ├── index.css
│ │ └── main.jsx
│ │
│ ├── public/
│ │ ├── favicon.svg
│ │ └── ...
│ ├── package.json
│ └── ...
│
├── backend/
│ ├── src/
│ │ ├── controllers/
│ │ │ └── messageController.js
│ │ │
│ │ ├── routes/
│ │ │ └── messageRoutes.js
│ │ │
│ │ ├── services/
│ │ │ └── messageService.js
│ │ │
│ │ ├── sockets/
│ │ │ └── chatSocket.js
│ │ │
│ │ └── server.js
│ │
│ ├── package.json
│ └── ...
│
├── .gitignore
└── README.md
The SQLite database is created automatically by the backend and is intentionally excluded from Git because it is runtime data.
Make sure the following are installed:
- Node.js
- npm
Clone the repository:
git clone <YOUR_GITHUB_REPOSITORY_URL>
cd realtime-chat-appOpen a terminal:
cd backend
npm installStart the backend:
npm startThe backend runs on:
http://localhost:5000
Health check:
http://localhost:5000/api/health
Expected response:
{
"success": true,
"message": "Chat server is running"
}For development with automatic restart:
npm run devOpen another terminal:
cd frontend
npm installStart the frontend:
npm run devThe frontend normally runs on:
http://localhost:5173
If Vite selects another available port, use the URL displayed in the terminal.
GET /api/messagesReturns previously stored messages from SQLite.
POST /api/messagesRequest body:
{
"username": "Bhanu",
"message": "Hello"
}The application primarily uses Socket.io for real-time message delivery while the REST API is available for the required backend operations.
The application uses Socket.io for real-time communication.
connection
join_chat
send_message
receive_message
online_users
typing_start
typing_stop
user_typing
user_stopped_typing
message_delivered
message_read
message_status_updated
SQLite is used for persistent message storage.
The database stores:
- Message ID
- Username
- Message content
- Timestamp
- Delivered status
- Read status
The database schema is initialized and migrated when the backend starts.
The database file is generated automatically on first backend startup and is excluded from version control.
No environment variables are required for the current local setup.
The backend uses:
PORT=5000
as the default port when no PORT environment variable is provided.
For deployment, the backend can use a platform-provided PORT value.
React was selected for the frontend because the assessment allows React and it provides a lightweight component-based architecture suitable for a real-time chat interface.
Socket.io is used as the primary real-time communication layer because real-time messaging is a mandatory requirement of the assessment.
Express provides REST endpoints for chat history and message operations.
SQLite was selected because the application requires persistent storage while keeping the project simple and easy to run locally without an external database server.
The UI is divided into reusable components such as:
ChatHeaderMessageBubbleMessageInputUsernameModal
API and Socket.io communication are separated into the services directory to keep networking logic outside the main UI components.
Backend responsibilities are separated into:
- Routes
- Controllers
- Services
- Socket handlers
This keeps the code easier to maintain and extend.
- Username login is dummy authentication and does not provide password-based authentication.
- Multiple users can connect using different usernames.
- The application is designed as a shared chat room.
- SQLite is used for local persistence.
- The current application is configured for local development using
localhost. - Message read/delivered status is implemented as an application-level chat status.
- The typing indicator is implemented through Socket.io events and disappears when typing stops or the message input loses focus.
The application handles common failures including:
- Backend/API request failures
- Socket connection/disconnection
- Invalid message input
- Invalid username/message data
- Database errors
- Socket message errors
The frontend displays appropriate connection and error states where required.
To test real-time communication:
- Start the backend.
- Start the frontend.
- Open the application in two browser windows/tabs.
- Use different usernames.
- Send a message from one window.
- Verify that the message appears instantly in the other window.
- Refresh the application and verify that previous messages remain available.
- Test the typing indicator and online-user status.
- Test delivered/read status on messages.
- Verify that disconnecting a browser updates the online-user count.
| Requirement | Implementation |
|---|---|
| React / React Native | React |
| Clean chat UI | React components + CSS |
| Send messages | Socket.io + REST API |
| Receive messages instantly | Socket.io |
| Previous messages after refresh | SQLite + REST API |
| Message timestamps | SQLite timestamp + frontend formatting |
| Node.js | Node.js |
| Express | Express |
| Send message API | POST /api/messages |
| Fetch history API | GET /api/messages |
| Socket.io mandatory | Implemented |
| Real-time broadcasting | Implemented |
| Connection handling | Implemented |
| Disconnection handling | Implemented |
| Clean folder structure | Implemented |
| Error handling | Implemented |
| README | This document |
| Username login | Bonus implemented |
| Typing indicator | Bonus implemented |
| Online user status | Bonus implemented |
| Read/delivered status | Bonus implemented |
| SQLite persistence | Bonus implemented |
- GitHub Repository: https://github.com/BhanuStackDev/real-time-chat
- README with setup instructions
For the web implementation, an APK is not required.
Bhanuday Urmaliya
Developed as a technical assessment project.