Skip to content

rishbad/Realtime-Chat-App

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ’¬ realtime-chat-app

A real-time chat application built for 50+ concurrent users

Node.js React Vite PostgreSQL Appwrite WebSocket License: MIT

Features Β· Architecture Β· Getting Started Β· API Reference Β· WebSocket Events Β· Contributing


✨ Features

  • ⚑ Real-time messaging via persistent WebSocket connections
  • 🏠 Public & private rooms β€” create, join, leave, and invite users via shareable links
  • πŸ’¬ Direct messages (DMs) β€” one-on-one conversations with contacts
  • πŸ‘₯ Contact system β€” send, accept, and reject contact requests
  • ✍️ Typing indicators β€” live "user is typing…" notifications
  • 🟒 Online presence β€” see who's currently active across all rooms
  • πŸ§‘β€πŸ’Ό User profiles β€” display name and profile picture support
  • πŸ“œ Persistent message history β€” stored in PostgreSQL, loaded on room join
  • πŸ”΄ Unread counts β€” per-room badge counts for missed messages
  • πŸ” JWT-based WebSocket auth β€” all connections authenticated via Appwrite-issued JWTs

πŸ— Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚         React Client            β”‚
β”‚  (Vite + Appwrite SDK)          β”‚
β”‚                                 β”‚
β”‚  Auth ──────── Appwrite         β”‚
β”‚  Realtime ───── WebSocket       β”‚
β”‚  Data ──────── Express REST     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚ HTTP + WebSocket
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚        Express Server           β”‚
β”‚  (Node.js + ws library)         β”‚
β”‚                                 β”‚
β”‚  REST API  ──── PostgreSQL      β”‚
β”‚  WebSocket ──── in-memory Maps  β”‚
β”‚  Auth verify ── Appwrite API    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚                 β”‚
β”Œβ”€β”€β”€β–Όβ”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”
β”‚  PG DB β”‚     β”‚  Appwrite   β”‚
β”‚ msgs   β”‚     β”‚ auth/users  β”‚
β”‚ rooms  β”‚     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚contactsβ”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜

The server maintains two in-memory structures for real-time routing:

  • onlineUsers: Map<userId, Set<WebSocket>> β€” all active connections per user
  • rooms: Map<roomId, Set<WebSocket>> β€” all subscribers per room

πŸš€ Getting Started

Prerequisites

  • Node.js >= 18.0.0
  • PostgreSQL database β€” local, or hosted (Supabase, Neon, Railway)
  • Appwrite project β€” cloud.appwrite.io or self-hosted, with Email/Password auth enabled

1. Clone the repository

git clone https://github.com/your-username/realtime-chat-app.git
cd realtime-chat-app

2. Set up Appwrite

  1. Create a project at cloud.appwrite.io.
  2. Enable Email/Password authentication under Auth β†’ Settings.
  3. Copy your Project ID and API Endpoint β€” you'll need them in both .env files below.

3. Configure the server

cd server
cp .env.example .env   # then fill in your values
npm install
server/.env reference
# Server
PORT=10000

# PostgreSQL
PGUSER=your_db_user
PGHOST=your_db_host
PGDATABASE=your_db_name
PGPASSWORD=your_db_password
PGPORT=5432

# Appwrite (used to verify JWTs)
APPWRITE_ENDPOINT=https://cloud.appwrite.io/v1
APPWRITE_PROJECT_ID=your_appwrite_project_id

# CORS β€” comma-separated list of allowed frontend origins
CORS_ORIGIN=http://localhost:5173

Database schema

Run the following SQL against your PostgreSQL database before starting the server:

CREATE TABLE IF NOT EXISTS users (
  id           TEXT PRIMARY KEY,
  email        TEXT UNIQUE NOT NULL,
  name         TEXT,
  status       TEXT      DEFAULT 'offline',
  last_seen    TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE IF NOT EXISTS rooms (
  id           TEXT PRIMARY KEY,
  name         TEXT NOT NULL,
  type         TEXT      DEFAULT 'public',
  created_by   TEXT,
  updated_at   TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE IF NOT EXISTS room_members (
  room_id      TEXT REFERENCES rooms(id),
  user_id      TEXT REFERENCES users(id),
  last_read_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (room_id, user_id)
);

CREATE TABLE IF NOT EXISTS messages (
  id           SERIAL PRIMARY KEY,
  room_id      TEXT REFERENCES rooms(id),
  user_id      TEXT,
  user_email   TEXT,
  content      TEXT NOT NULL,
  created_at   TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE IF NOT EXISTS contacts (
  id           SERIAL PRIMARY KEY,
  user_id      TEXT REFERENCES users(id),
  contact_id   TEXT REFERENCES users(id),
  status       TEXT      DEFAULT 'pending',
  created_at   TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  UNIQUE (user_id, contact_id)
);

4. Configure the client

cd ../client
cp .env.example .env   # then fill in your values
npm install
client/.env reference
VITE_APPWRITE_ENDPOINT=https://cloud.appwrite.io/v1
VITE_APPWRITE_PROJECT_ID=your_appwrite_project_id

VITE_API_URL=http://localhost:10000
VITE_WS_URL=ws://localhost:10000

5. Run the app

Start the server (terminal 1):

cd server
npm run dev     # nodemon β€” auto-reloads on save
# or
npm start       # plain node

Start the client (terminal 2):

cd client
npm run dev

Open http://localhost:5173 in your browser. πŸŽ‰


🌐 Deployment

Layer Recommended platforms
Server Railway, Render, Fly.io
Client Vercel, Netlify, Cloudflare Pages
Database Supabase, Neon, Railway

After deploying the server, update the client's VITE_API_URL and VITE_WS_URL to your server's public URL, and add the client's origin to the server's CORS_ORIGIN env var.


πŸ”‘ Environment Variables

Server (server/.env)

Variable Required Default Description
PORT No 10000 HTTP / WebSocket server port
PGUSER Yes β€” PostgreSQL username
PGHOST Yes β€” PostgreSQL host
PGDATABASE Yes β€” PostgreSQL database name
PGPASSWORD Yes β€” PostgreSQL password
PGPORT No 5432 PostgreSQL port
APPWRITE_ENDPOINT Yes http://localhost/v1 Appwrite API endpoint
APPWRITE_PROJECT_ID Yes β€” Appwrite project ID
CORS_ORIGIN No β€” Comma-separated list of allowed client origins

Client (client/.env)

Variable Required Default Description
VITE_APPWRITE_ENDPOINT Yes β€” Appwrite API endpoint
VITE_APPWRITE_PROJECT_ID Yes β€” Appwrite project ID
VITE_API_URL No http://localhost:3000 Express REST API base URL
VITE_WS_URL No ws://localhost:3000 WebSocket server URL

πŸ“‘ API Reference

All REST endpoints except /health require an x-user-id header with the authenticated user's Appwrite ID.

Method Endpoint Description
GET /health Server health check (uptime, users, rooms)
GET /api/rooms List rooms the current user belongs to
POST /api/rooms/create Create a new room
POST /api/rooms/join Join an existing room by ID
POST /api/rooms/leave Leave a room
POST /api/rooms/dm Create or retrieve a DM room with another user
POST /api/rooms/invite Generate an invite link for a room
POST /api/rooms/update Update a room's name
GET /api/messages/:roomId Fetch paginated message history for a room
GET /api/users/search Search users by email (?email=...)
GET /api/contacts List accepted contacts
GET /api/contacts/requests List pending incoming contact requests
POST /api/contacts/request Send a contact request to a user
POST /api/contacts/accept Accept a contact request
POST /api/contacts/reject Reject a contact request

πŸ”Œ WebSocket Events

After connecting, the client must authenticate by sending a JOIN message with a valid Appwrite JWT. All messages are JSON-encoded.

Client β†’ Server

Type Payload fields Description
JOIN token, userId, email Authenticate and register connection
JOIN_ROOM roomId Subscribe to a room's messages
ROOM_MESSAGE roomId, content Send a message to a room
TYPING_START roomId Notify room that user is typing
TYPING_STOP roomId Notify room that user stopped typing
PING β€” Keep-alive ping

Server β†’ Client

Type Payload fields Description
PONG β€” Keep-alive response
JOINED_ROOM roomId Confirms room subscription
ROOM_MESSAGE roomId, userId, content, createdAt, userEmail New message in a room
USER_JOINED roomId, userId, email A user joined the room
USER_LEFT roomId, userId A user left or disconnected
USER_TYPING roomId, userId, isTyping Typing indicator update
USER_STATUS userId, status User came online or went offline
ERROR message Error response from the server

πŸ“ Project Structure

realtime-chat-app/
β”œβ”€β”€ client/                    # React frontend (Vite)
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ App.jsx            # Main app β€” auth, chat, contacts, rooms
β”‚   β”‚   β”œβ”€β”€ main.jsx           # React entry point
β”‚   β”‚   β”œβ”€β”€ index.css          # Global styles
β”‚   β”‚   └── appwrite.js        # Appwrite client setup
β”‚   β”œβ”€β”€ index.html
β”‚   β”œβ”€β”€ vite.config.js
β”‚   β”œβ”€β”€ .env.example
β”‚   └── package.json
β”‚
└── server/                    # Node.js backend
    β”œβ”€β”€ index.js               # Express app, REST endpoints, WebSocket handler
    β”œβ”€β”€ db.js                  # PostgreSQL connection pool
    β”œβ”€β”€ .env.example
    └── package.json

πŸ›  Scripts

Server

Command Description
npm start Start the server with Node
npm run dev Start with nodemon (auto-reload on save)

Client

Command Description
npm run dev Start the Vite dev server
npm run build Build for production β†’ dist/
npm run preview Preview the production build locally

🀝 Contributing

Contributions are welcome! To get started:

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/your-feature-name
  3. Commit your changes: git commit -m 'Add some feature'
  4. Push to your branch: git push origin feature/your-feature-name
  5. Open a Pull Request

For major changes, please open an issue first so we can discuss the approach.


πŸ“„ License

This project is licensed under the MIT License β€” see the LICENSE file for details.


Made with ❀️  ·  Report a Bug  ·  Request a Feature

About

About Real-time chat application with 50+ user support

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors