| Service | URL |
|---|---|
| Frontend | lingua-chat.vercel.app |
| Backend | linguachat-frmz.onrender.com |
Create an account, join or create a room, and start chatting β messages are translated automatically for every participant.
LinguaChat is a full-stack, real-time multilingual chat application. Users speaking different languages can join the same room and communicate effortlessly β every message is automatically translated into each participant's preferred language using the Lingo.dev AI translation engine.
Built with a modern TypeScript stack: React 19 + Vite on the frontend and Node.js + Express + Socket.IO on the backend, backed by MongoDB Atlas for persistent storage.
- Real-time messaging via Socket.IO with instant delivery
- Automatic translation to 7 languages (English, Hindi, Bengali, Spanish, French, German, Japanese)
- Two-phase message delivery β original text appears instantly, translations arrive asynchronously
- Translation caching β repeated phrases are served instantly from an in-memory cache
- Create & join rooms β public rooms with admin controls
- Global / Native mode β admins can toggle between translated (Global) and untranslated (Native) modes per room
- Online presence β see who's in the room with live user lists and language tags
- Room history β last 50 messages loaded on join with on-the-fly translation for missing languages
- Emoji picker β inline emoji selection in the message composer
- Message reactions β react to messages with emojis (toggle on/off)
- Reply threads β reply to specific messages with a preview bar and scroll-to-message navigation
- Typing indicators β see when others are composing a message
- Date separators β messages grouped by Today / Yesterday / date labels
- Auto-resize composer β textarea grows with input, supports Shift+Enter for newlines
- JWT-based auth with access + refresh tokens
- Session management β view active sessions, logout individual or all sessions
- Rate limiting β per-route and per-socket rate limits to prevent abuse
- Input validation with Zod schemas
- Socket authentication middleware β only authenticated users can connect
- Frontend deployed on Vercel (SPA with client-side routing)
- Backend deployed on Render (Node.js Web Service)
- Database on MongoDB Atlas (cloud-hosted)
| Layer | Technologies |
|---|---|
| Frontend | React 19, TypeScript, Vite 7, Tailwind CSS 4, Socket.IO Client |
| Backend | Node.js, Express 5, TypeScript, Socket.IO 4, Mongoose |
| AI | Lingo.dev SDK β AI-powered translation engine |
| Database | MongoDB Atlas with Mongoose ODM |
| Auth | JWT (access + refresh tokens), bcrypt password hashing |
| Testing | Jest, Supertest, MongoDB Memory Server |
| Deploy | Vercel (frontend), Render (backend) |
LinguaChat/
β
βββ apps/
β βββ api/ # Node.js + Express + Socket.IO backend
β β βββ src/
β β β βββ server.ts # Entry point β HTTP server + Socket.IO setup
β β β βββ app.ts # Express app β CORS, rate limiting, routes
β β β βββ config/
β β β βββ controllers/
β β β βββ middlewares/
β β β βββ models/
β β β βββ routes/
β β β βββ services/
β β β βββ sockets/
β β β βββ types/
β β βββ tests/ # Jest test suites
β β βββ package.json
β β βββ tsconfig.json
β βββ web/ # React 19 + Vite SPA
β β βββ src/
β β β βββ main.tsx # App entry point
β β β βββ App.tsx # Router setup (login, register, home, room)
β β β βββ context/
β β β βββ components/
β β β βββ pages/
β β β βββ services/
β β β βββ types/
β β βββ vercel.json # SPA rewrite rules for Vercel
β β βββ package.json
β β βββ vite.config.ts
β βββ mobile/ # Expo + React Native client
βββ packages/
β βββ shared/ # Shared chat + socket contracts
βββ package.json # Root workspace scripts
- Node.js 18+ (recommended: 22)
- MongoDB β local instance or MongoDB Atlas (free tier)
- Lingo.dev API Key β get one at lingo.dev
The fastest way to get everything running. Only requires Docker installed.
git clone https://github.com/Souma061/LinguaChat.git
cd LinguaChatcp apps/api/.env.example apps/api/.envEdit apps/api/.env and fill in your credentials:
LINGO_API_KEY=your_lingo_api_key
PORT=5000
MONGODB_URI=mongodb+srv://user:password@cluster.mongodb.net/
JWT_SECRET=your_jwt_secret
JWT_REFRESH_SECRET=your_refresh_secret
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret
CORS_ORIGINS=http://localhostNeed API keys?
- Lingo.dev β sign up at lingo.dev (free tier available)
- MongoDB Atlas β create a free cluster at mongodb.com/atlas
- Cloudinary β sign up at cloudinary.com (free tier)
docker compose up --build -d| Service | URL |
|---|---|
| Frontend | http://localhost |
| Backend | http://localhost:5000 |
docker compose down # stop
docker compose up -d # restart (without rebuilding)
docker compose up --build -d # restart with rebuild- Node.js 18+ (recommended: 22)
- npm (comes with Node.js)
git clone https://github.com/Souma061/LinguaChat.git
cd LinguaChatnpm --prefix apps/api installCreate a .env file:
LINGO_API_KEY=your_lingo_api_key
PORT=5000
MONGODB_URI=mongodb+srv://user:password@cluster.mongodb.net/
JWT_SECRET=your_jwt_secret
JWT_REFRESH_SECRET=your_refresh_secret
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret
CORS_ORIGINS=http://localhost:5173,http://localhost:5174Start the development server:
npm run dev:apiBackend runs on
http://localhost:5000
npm --prefix apps/web installCreate a .env file:
VITE_BACKEND_URL=http://localhost:5000/api
VITE_SOCKET_URL=http://localhost:5000Start the development server:
npm run dev:webFrontend runs on
http://localhost:5173
cp apps/mobile/.env.example apps/mobile/.env
npm --prefix apps/mobile installStart the Expo development server:
npm run dev:mobileMobile runs through Expo and talks to the same backend in
apps/api
npm run test:apiTests use Jest with MongoDB Memory Server for isolated database testing and Supertest for HTTP endpoint validation.
| Model | Purpose |
|---|---|
| User | Username, email, hashed password, role |
| Room | Name, owner, admins, members, mode (Global/Native) |
| Message | Original text, translations map, reactions, replies |
| UserSession | JWT session tracking for multi-device logout |
{
room: string; // Room identifier (indexed)
author: string; // Sender's username
original: string; // Original untranslated message
translations: Map; // { langCode: translatedText }
sourceLocale: string; // Detected source language
msgId: string; // Unique message identifier
reactions: Map; // { emoji: [username1, username2] }
replyTo?: { // Optional reply reference
msgId: string;
author: string;
message: string;
};
createdAt: Date; // Auto-managed timestamp
}roomβ fast room filtering{ room, createdAt }β compound index for efficient history retrievalmsgIdβ unique constraint for deduplication
LinguaChat uses a two-phase message delivery pattern for optimal UX:
- Phase 1 β Instant delivery: Message is saved to MongoDB and broadcast to all room members immediately with the original text.
- Phase 2 β Async translation: Translations are generated in the background via Lingo.dev SDK, then pushed to all clients via a
translations_readysocket event.
This ensures messages appear instantly while translations arrive within seconds.
| Code | Language |
|---|---|
en |
English |
hi |
Hindi |
bn |
Bengali |
es |
Spanish |
fr |
French |
de |
German |
ja |
Japanese |
- Create a Web Service on Render
- Connect your GitHub repository
- Configure:
- Root Directory:
apps/api - Build Command:
npm install && npm run build - Start Command:
npm start
- Root Directory:
- Add environment variables (
MONGODB_URI,JWT_SECRET,JWT_REFRESH_SECRET,LINGO_API_KEY,CORS_ORIGINS)
- Import the repository on Vercel
- Set Root Directory to
apps/web - Add environment variables:
VITE_BACKEND_URL=https://your-backend.onrender.com/apiVITE_SOCKET_URL=https://your-backend.onrender.com
- Deploy β Vercel auto-detects Vite and builds accordingly
Important: Add your Vercel domain to
CORS_ORIGINSin the Render environment variables after deployment.
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| POST | /api/auth/register |
Create a new account | β |
| POST | /api/auth/login |
Login & receive tokens | β |
| POST | /api/auth/refresh-token |
Refresh access token | β |
| POST | /api/auth/logout-session |
Logout current session | β |
| POST | /api/auth/logout-all |
Logout all sessions | β |
| GET | /api/auth/sessions |
List active sessions | β |
| GET | /api/auth/profile |
Get user profile | β |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| GET | /api/rooms |
List public rooms | β |
| POST | /api/rooms |
Create a new room | β |
| Event | Direction | Description |
|---|---|---|
join_Room |
Client β Server | Join a chat room |
send_message |
Client β Server | Send a message to the room |
set_language |
Client β Server | Change preferred language |
create_room |
Client β Server | Create a new room |
update_room_mode |
Client β Server | Toggle Global/Native mode (admin only) |
add_reaction |
Client β Server | React to a message with an emoji |
typing_start |
Client β Server | Notify typing started |
typing_stop |
Client β Server | Notify typing stopped |
receive_message |
Server β Client | New message received |
translations_ready |
Server β Client | Translations available for a message |
room_history |
Server β Client | Room message history on join |
room_users |
Server β Client | Updated list of online users |
room_info |
Server β Client | Room mode and admin status |
reaction_update |
Server β Client | Updated reactions for a message |
user_typing |
Server β Client | Typing indicator from another user |
error_event |
Server β Client | Error notification |
| Landing Screen | Demo Room | Cross-Language Chat |
|---|---|---|
![]() |
![]() |
![]() |
This project is open source under the ISC License.
Built with β€οΈ for the Lingo.dev Hackathon β making global communication effortless.


