A high-performance, cross-platform real-time chat application built with Flutter, Node.js, Express, Socket.IO, and MongoDB.
ChatApp is a full-stack, production-ready real-time instant messaging application designed for seamless one-to-one communication across mobile (Android & iOS) and web platforms.
Built with a modern reactive architecture, the application combines a responsive Flutter & Riverpod frontend with an asynchronous Node.js, Express, Socket.IO, and MongoDB backend. The system features persistent bidirectional WebSockets for instant message delivery, live typing status, real-time online/offline presence indicators, optimistic UI state management, paginated chat history, and JWT-authenticated session security.
- User Registration & Login: Account creation and login with form validation (email format, password minimum length).
- Password Hashing: Passwords are encrypted before storage using bcrypt with a salt round of 10.
- JWT Authorization: Stateless access token generation (
jsonwebtoken) with configurable expiration (JWT_EXPIRES_IN=7d). - Encrypted Local Storage: Authentication tokens are safely stored on the device using Flutter Secure Storage (Android Keystore / iOS Keychain).
- Auto-Login & Session Recovery: App verifies stored tokens on startup via
/api/auth/meand seamlessly restores user sessions. - Session Expiration Guard: Automatic 401 interceptor that clears expired tokens and redirects the user to the login screen.
- Protected Endpoints & Sockets: All private REST endpoints and Socket.IO handshake connections require valid Bearer tokens.
- Security Middleware: Configured with Helmet for HTTP security headers, CORS origin verification, and Express Rate Limiting to prevent brute-force attacks.
- Instant 1-on-1 Chat: Bi-directional real-time communication powered by Socket.IO rooms (
user_<id>and<chatId>). - Optimistic UI Updates: Sent messages appear immediately in the chat thread with temporary local IDs before server confirmation.
- REST Fallback Transmission: If socket connectivity is momentarily interrupted, the client transparently falls back to REST API message posting.
- Typing Indicators: Real-time broadcast of typing state (
typingandstop_typing) with automatic 1.5s debouncing timers. - Live User Presence: Instant online/offline status tracking with broadcast events (
user_online,user_offline,check_online_status). - Read Receipts & Delivery Tracking: Real-time read acknowledgment (
mark_read,message_read,messages_read) with timestamps and visual status checkmarks. - Global In-App Notifications: Background socket listeners automatically update the Home screen's chat list when new messages arrive.
- Paginated Message Loading: Reverse infinite scrolling with backend pagination (
skip&limit) for fast startup and low memory usage. - Smart Conversation Creation: Automated lookup or creation of unique, normalized 1-on-1 chat threads between participant pairs.
- Recent Chat Ordering: Active conversations are dynamically sorted by latest message timestamp (
updatedAt/lastMessageAt). - Empty States & Shimmers: Designed with polished empty states for new conversations and initial message feeds.
- Debounced User Search: Live search query system across names and emails with a 400ms debounce to prevent superfluous API calls.
- Profile Customization: Users can edit their display names and view their account email.
- Avatar Photo Upload: Native photo library selection (
image_picker) and multipart upload via Multer with MIME-type filtering. - Initials Fallback Avatars: Automatic generation of colored monogram avatars for contacts without custom profile images.
The application includes a clean Material 3 user interface designed with a cohesive color palette (Deep Emerald #075E54, Vibrant Green #25D366, and Warm Chat Beige #ECE5DD).
| Register Screen | Login Screen | Empty Chats State |
|---|---|---|
![]() |
![]() |
![]() |
| User registration with validation | Email & password sign-in | Clean initial landing empty state |
| User Search Screen | Active Chat Room | Active Chat List |
|---|---|---|
![]() |
![]() |
![]() |
| Debounced user search by name/email | 1-on-1 chat with status & bubbles | Recent chats with unread & preview |
| Profile View | Photo Attachment Picker | Updated Avatar Profile |
|---|---|---|
![]() |
![]() |
![]() |
| View and edit account information | Native photo gallery picker | Live avatar image update |
| Settings Screen | Logout Confirmation | Cross-Platform Live Sync |
|---|---|---|
![]() |
![]() |
![]() |
| Account & app preferences | Secure session sign-out dialog | Real-time sync on iOS & Android |
The backend utilizes MongoDB via Mongoose with optimized indexes on lookup fields, timestamps, and relational ObjectIds.
MongoDB mongosh session displaying active database chatapp, collections (chats, messages, users), and indexed documents.
| Collection | Model File | Purpose & Stored Attributes | Indexes |
|---|---|---|---|
users |
User.js |
Stores user profiles: name, email (unique, lowercase), password (bcrypt hash, select: false), avatar URL, isOnline boolean, lastSeen date, createdAt, updatedAt. |
Unique index on email, Compound text index on { name: "text", email: "text" }. |
chats |
Chat.js |
Stores 1-on-1 conversation records: participants (Array of 2 User ObjectIds), lastMessage (Message ObjectId reference), lastMessageAt date, createdAt, updatedAt. |
Index on participants, Descending index on updatedAt. |
messages |
Message.js |
Stores individual chat messages: chatId (Chat reference), sender (User reference), receiver (User reference), message text, messageType (text, image, file, emoji), fileUrl, fileName, fileSize, isRead, readAt, delivered, deliveredAt. |
Compound index on { chatId: 1, createdAt: -1 }, { sender: 1, receiver: 1 }, { isRead: 1 }, { delivered: 1 }. |
- Connected via Mongoose in
backend/src/config/database.jsusing theMONGO_URIenvironment variable. - Connection state is monitored and exposed via the
/healthdiagnostic endpoint (mongodb: connected).
flowchart TB
subgraph Client["Flutter Cross-Platform Frontend"]
UI["UI Layer (Material 3 Screens & Widgets)"]
State["Riverpod State Notifiers (Auth, Chat, Message, Socket)"]
Router["GoRouter (Route Guards & Redirection)"]
Storage["Flutter Secure Storage (JWT Auth Token)"]
DioClient["Dio HTTP Client (REST with Bearer Interceptor)"]
SocketClient["Socket.IO Client (WebSocket Connection)"]
UI --> State
State --> Router
State --> Storage
State --> DioClient
State --> SocketClient
end
subgraph Gateway["Express & Socket Gateway (Port 5001)"]
MW["Middleware (Helmet, CORS, Morgan, RateLimiter, Multer)"]
AuthMW["JWT Auth Middleware & Socket Handshake Auth"]
subgraph RESTControllers["Express REST API"]
AuthCtrl["Auth Controller (/api/auth)"]
UserCtrl["User Controller (/api/users)"]
ChatCtrl["Chat Controller (/api/chats)"]
end
subgraph SocketEngine["Socket.IO Engine"]
Presence["Presence Engine (user_online / user_offline)"]
MsgRelay["Message Relay (send_message -> receive_message)"]
Typing["Typing Handler (typing / stop_typing)"]
ReadRec["Read Receipts (mark_read / message_read)"]
end
DioClient -- "HTTP REST Requests" --> MW --> AuthMW --> RESTControllers
SocketClient -- "WebSocket Events" --> AuthMW --> SocketEngine
end
subgraph Database["Database & File Persistence"]
MongoDB[(MongoDB Database: 'chatapp')]
Uploads[("/uploads Static Avatar Storage")]
RESTControllers --> MongoDB
SocketEngine --> MongoDB
UserCtrl --> Uploads
end
sequenceDiagram
autonumber
actor User as User
participant App as Flutter App
participant Storage as Secure Storage
participant API as Express API
participant DB as MongoDB
User->>App: Launch App
App->>Storage: Read 'auth_token'
alt Token Found
App->>API: GET /api/auth/me (Bearer Token)
alt Token Valid
API->>DB: User.findById(decoded.userId)
DB-->>API: User Document
API-->>App: { success: true, user }
App->>App: Navigate to /home
else Token Expired / Invalid
API-->>App: 401 Unauthorized
App->>Storage: Delete 'auth_token'
App->>App: Navigate to /login
end
else No Token Found
App->>App: Navigate to /login
end
sequenceDiagram
autonumber
actor UserA as Alice (Sender)
participant ClientA as Alice's App
participant Server as Socket.IO Server
participant DB as MongoDB
participant ClientB as Bob's App
actor UserB as Bob (Receiver)
Note over ClientA, Server: Connected & Joined Rooms ('user_AliceID', 'chat_123')
Note over ClientB, Server: Connected & Joined Rooms ('user_BobID', 'chat_123')
UserA->>ClientA: Types message in ChatScreen
ClientA->>Server: emit('typing', { chatId, receiver: BobID })
Server-->>ClientB: emit('typing', { userId: AliceID, chatId })
ClientB->>UserB: Display Typing Indicator (β β β)
UserA->>ClientA: Press Send Button
ClientA->>ClientA: Render optimistic message bubble (temp_id)
ClientA->>Server: emitWithAck('send_message', { chatId, receiver, message })
Server->>DB: Message.create() & Chat.update(lastMessage)
DB-->>Server: Saved Message Document
Server-->>ClientA: Ack / emit('message_sent', savedMessage)
ClientA->>ClientA: Replace temp_id with permanent MongoDB _id
Server-->>ClientB: emit('receive_message', savedMessage)
ClientB->>UserB: Display incoming message bubble
ClientB->>Server: emit('mark_read', { chatId })
Server->>DB: Message.updateMany({ chatId, isRead: true })
Server-->>ClientA: emit('message_read', { chatId, readBy: BobID })
ClientA->>UserA: Update message bubble to Double Checkmarks (Read)
frontend/
βββ assets/
β βββ logo.png # App icon and branding asset
βββ lib/
β βββ main.dart # Application entry point, dotenv initialization & ProviderScope
β βββ core/
β β βββ api/
β β β βββ api_client.dart # Dio HTTP instance, auth interceptors & Android localhost rewriter
β β β βββ api_endpoints.dart # Centralized REST route constants
β β β βββ environment.dart # Environment config and fallback URLs
β β β βββ socket_client.dart # Socket.IO client singleton abstraction
β β βββ constants/
β β βββ app_colors.dart # Material 3 theme color palette
β β βββ app_strings.dart # Localized UI string constants & storage keys
β β βββ app_theme.dart # ThemeData definition (AppBar, Buttons, Inputs)
β βββ models/
β β βββ api_response.dart # Generic API response wrapper model
β β βββ chat.dart # Chat room model & participant resolver
β β βββ message.dart # Message entity model & type parser (text/image/file/emoji)
β β βββ user.dart # User entity model (Equatable)
β βββ providers/
β β βββ auth_provider.dart # AuthStateNotifier (login, register, auto-login, logout)
β β βββ chat_provider.dart # ChatListNotifier (live chat list state & ordering)
β β βββ message_provider.dart # ChatMessagesNotifier (chat room state, pagination, optimistic UI)
β β βββ socket_provider.dart # SocketController & OnlineUsersNotifier (global presence)
β β βββ user_provider.dart # UserSearchNotifier & ProfileEditNotifier
β βββ routes/
β β βββ app_router.dart # GoRouter configuration with auth-state refresh listeners
β βββ screens/
β β βββ chat/
β β β βββ widgets/
β β β β βββ chat_input_field.dart # Chat textfield with dynamic send button
β β β β βββ message_bubble.dart # Chat bubble with timestamp and delivery status
β β β β βββ message_input.dart # Auxiliary input components
β β β β βββ typing_indicator.dart # Animated pulsing typing indicator
β β β βββ chat_screen.dart # 1-on-1 chat room with reverse pagination
β β βββ home/
β β β βββ widgets/
β β β β βββ chat_list_tile.dart # Chat tile with avatar, last message preview & unread dot
β β β βββ home_screen.dart # Recent conversations feed with search FAB
β β βββ login/
β β β βββ login_screen.dart # Sign-in form with email/password validation
β β βββ profile/
β β β βββ profile_screen.dart # Profile editing & avatar image picker upload
β β βββ register/
β β β βββ register_screen.dart # Account registration form
β β βββ search/
β β β βββ user_search_screen.dart # Live debounced user search & direct chat initiation
β β βββ settings/
β β β βββ settings_screen.dart # Settings list & logout confirmation modal
β β βββ splash/
β β βββ splash_screen.dart # Startup splash screen during auth verification
β βββ services/
β β βββ auth_service.dart # REST authentication endpoints service
β β βββ chat_service.dart # REST chat creation & fetch service
β β βββ message_service.dart # REST message pagination & fallback service
β β βββ socket_service.dart # Low-level Socket.IO emitter and listener wrapper
β β βββ storage_service.dart # FlutterSecureStorage wrapper for tokens
β β βββ user_service.dart # REST user search and avatar upload service
β βββ utils/
β β βββ date_formatter.dart # Time formatting for chat timestamps
β β βββ validators.dart # Form validation logic (Email, Password, Name)
β βββ widgets/
β βββ custom_button.dart # Reusable primary action button with loading spinner
β βββ custom_text_field.dart # Reusable styled text input with prefix/suffix icons
β βββ empty_state.dart # Reusable placeholder illustration & caption widget
β βββ error_widget.dart # Reusable error display with retry callback
β βββ loading_indicator.dart # Centered progress indicator
βββ pubspec.yaml # Flutter project configuration and package dependencies
βββ analysis_options.yaml # Dart analyzer and linting rules
backend/
βββ src/
β βββ config/
β β βββ cors.js # Dynamic CORS origin validator & Socket.IO CORS rules
β β βββ database.js # Mongoose connection initialization
β βββ controllers/
β β βββ authController.js # Register, login, getMe, logout handlers
β β βββ chatController.js # Fetch chats, create chat, get messages, send message, mark read
β β βββ userController.js # Get users, search users, update profile, upload avatar
β βββ middleware/
β β βββ auth.js # JWT verification middleware for protected routes
β β βββ errorHandler.js # Centralized JSON error responder with environment checks
β β βββ rateLimiter.js # Express-rate-limit configuration
β β βββ upload.js # Multer diskStorage and image fileFilter configuration
β βββ models/
β β βββ Chat.js # Mongoose schema for conversations
β β βββ Message.js # Mongoose schema for messages
β β βββ User.js # Mongoose schema for users (with password hiding & index rules)
β βββ routes/
β β βββ authRoutes.js # Route definitions for /api/auth
β β βββ chatRoutes.js # Route definitions for /api/chats
β β βββ userRoutes.js # Route definitions for /api/users
β βββ sockets/
β β βββ events.js # Socket message sending, typing broadcast & read handlers
β β βββ index.js # Socket.IO connection lifecycle & auth middleware
β βββ utils/
β β βββ bcrypt.js # Password hashing and comparison utilities
β β βββ jwt.js # JWT signing and verification helpers
β βββ validators/
β β βββ authValidator.js # Express-validator rules for registration & login
β β βββ chatValidator.js # Express-validator rules for messages
β βββ app.js # Express app configuration, route mounting & /health endpoint
β βββ server.js # HTTP server, Socket.IO binding & port listener
βββ uploads/ # Static storage directory for uploaded user avatars
βββ .env.example # Environment variable template
βββ package.json # Node.js dependencies, scripts and package metadata
- Framework: Flutter (v3.x / Dart SDK ^3.12.2)
- State Management: Riverpod (
flutter_riverpod: ^3.4.2) - Navigation & Routing: GoRouter (
go_router: ^17.4.0) - HTTP Client: Dio (
dio: ^5.11.0) - WebSocket Client: Socket.IO Client (
socket_io_client: ^3.1.6) - Secure Storage: Flutter Secure Storage (
flutter_secure_storage: ^10.3.1) - Image Caching & Media: Cached Network Image (
cached_network_image: ^3.4.1), Image Picker (image_picker: ^1.2.3), File Picker (file_picker: ^8.1.6) - Utilities: Equatable (
equatable: ^2.1.0), Intl (intl: ^0.20.3), Flutter DotEnv (flutter_dotenv: ^6.0.1)
- Runtime Environment: Node.js (v18+ / v20+ recommended)
- Web Framework: Express.js (
express: ^5.2.1) - Real-Time Engine: Socket.IO (
socket.io: ^4.8.3) - Database ODM: Mongoose (
mongoose: ^9.9.1) - Authentication: JSON Web Tokens (
jsonwebtoken: ^9.0.3) & bcrypt (bcrypt: ^6.0.0) - Security & Validation: Helmet (
helmet: ^8.3.0), CORS (cors: ^2.8.6), Express Rate Limit (express-rate-limit: ^8.6.1), Express Validator (express-validator: ^7.3.2) - File Uploads: Multer (
multer: ^2.2.0) - Logging & Dev Tools: Morgan (
morgan: ^1.11.0), Nodemon (nodemon: ^3.1.14), Dotenv (dotenv: ^17.4.2)
- Database: MongoDB (Local Community Server or MongoDB Atlas Cloud)
Before getting started, make sure you have the following installed on your development machine:
| Requirement | Minimum / Recommended Version | Verification Command |
|---|---|---|
| Flutter SDK | >= 3.12.2 |
flutter --version |
| Dart SDK | >= 3.12.2 |
dart --version |
| Node.js | >= 18.0.0 (LTS Recommended) |
node --version |
| npm | >= 9.0.0 |
npm --version |
| MongoDB | >= 6.0 (Local or MongoDB Atlas) |
mongosh --version |
| Git | >= 2.30.0 |
git --version |
| Android Studio / Xcode | Latest stable (for emulator & simulator testing) | flutter doctor |
Verify your Flutter environment by running:
flutter doctorFollow these step-by-step instructions to set up and run the application locally.
git clone https://github.com/manab-ghh/basic-chat-app.git
cd basic-chat-app-
Navigate to the
backenddirectory:cd backend -
Install the required Node.js dependencies:
npm install
-
Create your
.envconfiguration file from the provided example template:cp .env.example .env
-
Open
.envand verify the settings (see Environment Variables for details). -
Start the backend development server:
npm run dev
The server will start on port
5001(or your configuredPORT) and connect to MongoDB.
-
Open a new terminal window and navigate to the
frontenddirectory:cd frontend -
Install Flutter package dependencies:
flutter pub get
-
Ensure a
.envfile exists in thefrontend/directory (or create one):cat <<EOF > .env BASE_URL=http://localhost:5001/api SOCKET_URL=http://localhost:5001 EOF
[!TIP] Android Emulator Support: The frontend codebase automatically rewrites
localhostand127.0.0.1to10.0.2.2when running on Android emulators, so you do not need to manually change the URL. -
Launch the Flutter application:
# Run on the default connected device / simulator flutter run # Or run explicitly on Android / iOS / Chrome flutter run -d chrome flutter run -d ios flutter run -d android
| Variable | Required | Default / Example | Purpose |
|---|---|---|---|
PORT |
No | 5001 |
The HTTP & WebSocket server port. |
NODE_ENV |
No | development |
Environment mode (development or production). |
MONGO_URI |
Yes | mongodb://localhost:27017/chatapp |
MongoDB connection URI string (Local or Atlas). |
JWT_SECRET |
Yes | your_super_secret_jwt_key_here |
Secret key used to sign and verify JWT authentication tokens. |
JWT_EXPIRES_IN |
No | 7d |
Lifespan of generated JWT tokens. |
CLIENT_URL |
No | http://localhost:3000 |
Allowed client origins for CORS validation. |
MAX_FILE_SIZE |
No | 5242880 |
Maximum file upload size in bytes (5 MB). |
UPLOAD_DIR |
No | uploads/ |
Destination folder for uploaded avatar files. |
RATE_LIMIT_WINDOW |
No | 15 |
Rate limiting window duration in minutes. |
RATE_LIMIT_MAX |
No | 100 |
Maximum requests allowed per IP per time window. |
| Variable | Required | Default / Example | Purpose |
|---|---|---|---|
BASE_URL |
Yes | http://localhost:5001/api |
Base URL for REST API calls. |
SOCKET_URL |
Yes | http://localhost:5001 |
Server URL for Socket.IO WebSocket connections. |
You can run MongoDB locally or use MongoDB Atlas in the cloud.
- Start your local MongoDB server:
# macOS (Homebrew) brew services start mongodb-community # Linux (systemd) sudo systemctl start mongod # Windows net start MongoDB
- Verify connection via
mongosh:mongosh
- Set your
MONGO_URIinbackend/.env:MONGO_URI=mongodb://localhost:27017/chatapp
- Log in to MongoDB Atlas and create a free Shared Cluster.
- Under Database Access, create a database user with password authentication.
- Under Network Access, add
0.0.0.0/0(or your specific IP) to the IP Access List. - Click Connect > Drivers (Node.js) to obtain your connection URI.
- Set the URI in
backend/.env:MONGO_URI=mongodb+srv://<username>:<password>@<cluster-url>/chatapp?retryWrites=true&w=majority
The application uses JSON Web Tokens (JWT) for secure, stateless authentication.
- Registration (
POST /api/auth/register): Validates email uniqueness and formats, hashes password withbcrypt, creates user, and returns user profile with JWT. - Login (
POST /api/auth/login): Validates credentials against hashed password, updateslastSeen, and issues a new JWT. - Token Storage: Flutter saves the token securely via
FlutterSecureStorageunder the keyauth_token. - REST Authorization: The
ApiClientDio interceptor automatically attaches the headerAuthorization: Bearer <token>to all protected endpoints. - Socket Authorization: The
SocketServicesupplies the token in the socket connection handshake:socket = io(socketUrl, { auth: { token: token }, transports: ['websocket'] });
- Token Verification: Backend middleware
auth.jsverifies the token signature and attaches the activeUserdocument toreq.user.
| Method | Endpoint | Auth Required | Description |
|---|---|---|---|
POST |
/api/auth/register |
No | Register a new user account. |
POST |
/api/auth/login |
No | Authenticate user and obtain a JWT token. |
GET |
/api/auth/me |
Yes | Retrieve authenticated user's profile. |
POST |
/api/auth/logout |
Yes | Logout user session. |
POST /api/auth/register
Content-Type: application/json
{
"name": "Manabendra Mondal",
"email": "manab@dev.com",
"password": "securepassword123"
}Response (201 Created):
{
"success": true,
"message": "User registered successfully",
"data": {
"user": {
"id": "66c75a1b2e1f3a001a123456",
"name": "Manabendra Mondal",
"email": "manab@dev.com",
"avatar": null,
"isOnline": false,
"lastSeen": "2026-08-23T10:00:00.000Z",
"createdAt": "2026-08-23T10:00:00.000Z",
"updatedAt": "2026-08-23T10:00:00.000Z"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}| Method | Endpoint | Auth Required | Description |
|---|---|---|---|
GET |
/api/users |
Yes | Get all registered users (excluding current user). |
GET |
/api/users/search?q=:query |
Yes | Search users by name or email (min 2 chars). |
PUT |
/api/users/profile |
Yes | Update name or avatar URL. |
POST |
/api/users/avatar |
Yes | Upload an avatar image file (multipart/form-data). |
| Method | Endpoint | Auth Required | Description |
|---|---|---|---|
GET |
/api/chats |
Yes | Get all active conversation threads for current user. |
POST |
/api/chats |
Yes | Get existing chat or create new chat with userId. |
GET |
/api/chats/:chatId/messages |
Yes | Get paginated message history (?page=1&limit=20). |
POST |
/api/chats/messages |
Yes | Send message via REST fallback. |
PUT |
/api/chats/:chatId/read |
Yes | Mark all unread messages in chat as read. |
join_room:{ "chatId": "string" }β Join a specific chat room.leave_room:{ "chatId": "string" }β Leave a chat room.send_message:{ "chatId": "string", "receiver": "string", "message": "string", "messageType": "text" }β Send real-time message.typing:{ "chatId": "string", "receiver": "string" }β Broadcast typing indicator.stop_typing:{ "chatId": "string", "receiver": "string" }β Clear typing indicator.mark_read:{ "chatId": "string" }β Mark received messages as read.check_online_status:{ "targetUserId": "string" }β Request presence status for a user.
receive_message: Emitted to recipient room (user_<receiverId>) and chat room with the new message payload.message_sent: Emitted back to sender with confirmed message payload.user_online: Broadcast when a user connects ({ "userId": "string", "isOnline": true }).user_offline: Broadcast when a user disconnects ({ "userId": "string", "isOnline": false, "lastSeen": Date }).typing/stop_typing: Forwarded to the recipient user.message_read/messages_read: Emitted to chat room when messages are read.online_status: Responded tocheck_online_status.
cd backend
npm run devcd frontend
flutter run- Ensure MongoDB is running (Local service or Atlas cluster reachable).
- Start Backend on port
5001(npm run dev). - Launch Frontend via Flutter (
flutter run). - Register two accounts (e.g. across two simulators/browsers) and start real-time messaging!
- Clone the repository
- Node.js and Flutter SDK prerequisites verified
- MongoDB database started and accessible
-
backend/.envconfigured withMONGO_URIandJWT_SECRET - Backend dependencies installed (
npm install) - Backend server running on
http://localhost:5001 - Frontend dependencies installed (
flutter pub get) - Frontend
.envconfigured withBASE_URLandSOCKET_URL - User registration & login verified
- Real-time messaging, typing indicators, and presence verified
- Cause: Local MongoDB daemon is not running, or Atlas IP whitelist does not permit connection.
- Solution:
- For local: Start MongoDB with
brew services start mongodb-communityorsudo systemctl start mongod. - For Atlas: Add
0.0.0.0/0under Network Access in MongoDB Atlas console.
- For local: Start MongoDB with
- Cause: A background Node process is already using port
5001. - Solution: Terminate the existing process or change
PORTin.env:lsof -ti :5001 | xargs kill -9
- Cause: Android emulators refer to their own host loopback when using
localhost. - Solution: The app includes built-in rewriting (
10.0.2.2), but ensurebackend/.envallows CORS from local origins.
- Cause: Browser requests blocked by CORS headers.
- Solution: Add your web origin URL to
CLIENT_URLinbackend/.env(e.g.CLIENT_URL=http://localhost:3000,http://localhost:8080).
- Never Commit Secrets: Ensure
.envis listed in.gitignoreand never committed to public repositories. - Strong JWT Secrets: Generate cryptographically secure keys (e.g.
openssl rand -base64 32) forJWT_SECRET. - Bcrypt Salt Hashing: All user passwords are salted and hashed with
bcryptprior to database persistence. - Sanitized JSON Output: User Mongoose schema strips
passwordand__vfrom all JSON responses. - Rate Limiting: Protected API routes use
express-rate-limitto mitigate brute-force and DoS attempts. - HTTPS & WSS in Production: Always enable SSL/TLS termination in production environments.
- Group Chats: Create group conversations with multiple participants and admin management.
- Push Notifications: Firebase Cloud Messaging (FCM) integration for background message delivery.
- Media & Audio Messages: Voice notes, audio recording, and full document file sharing.
- Message Reactions: Quick emoji reactions on individual message bubbles.
- End-to-End Encryption (E2EE): Signal Protocol integration for zero-knowledge end-to-end encryption.
- Dark Mode Theme: Dynamic theme switching (Light / Dark mode).
- Message Deletion & Editing: "Delete for everyone" and message edit history.
basic-chat-app/
βββ app-screens/ # Application screenshots and terminal previews
β βββ database.png # MongoDB mongosh collections preview
β βββ screen01.png # Register screen
β βββ screen02.png # Login screen
β βββ screen03.png # Empty chats screen
β βββ screen04.png # Profile screen
β βββ screen05.png # Settings screen
β βββ screen06.png # Logout dialog
β βββ screen07.png # User search screen
β βββ screen08.png # 1-on-1 chat room screen
β βββ screen09.png # Active chat list screen
β βββ screen10.png # Photo picker interface
β βββ screen11.png # Profile avatar updated
β βββ screen12.png # Dual device live cross-platform sync
βββ backend/ # Node.js + Express + Socket.IO backend
β βββ src/ # Server source code (controllers, models, routes, sockets)
β βββ uploads/ # Avatar uploads directory
β βββ .env.example # Backend environment variables template
β βββ package.json # Node dependencies & start scripts
βββ frontend/ # Flutter cross-platform mobile & web client
β βββ assets/ # App logos and images
β βββ lib/ # Dart source code (screens, providers, services, models)
β βββ pubspec.yaml # Flutter dependencies and asset registrations
β βββ analysis_options.yaml # Linting configuration
βββ .gitignore # Git ignore rules for Flutter, Node, and .env
βββ README.md # Project documentation
The backend package configuration specifies the ISC License. For repository-wide usage terms, refer to project settings or repository maintainers.
Manabendra Mondal
- GitHub: @manab-ghh
- Email: manabendra2006mondal@gmail.com
- Repository: https://github.com/manab-ghh/basic-chat-app
Built with β€οΈ by Manabendra Mondal using Flutter & Node.js













