Skip to content
  • SiteMap
  • Our Services
  • Frequently Asked Questions (FAQ)
  • Support
  • About Us

UpdateGadh

Update Your Skills.

  • Home
  • Projects
    •  Blockchain projects
    • Python Project
    • Data Science
    •  Ai projects
    • Machine Learning
    • PHP Project
    • React Projects
    • Java Project
    • SpringBoot
    • JSP Projects
    • Java Script Projects
    • Code Snippet
    • Free Projects
  • Tutorials
    • Ai
    • Machine Learning
    • Advance Python
    • Advance SQL
    • DBMS Tutorial
    • Data Analyst
    • Deep Learning Tutorial
    • Data Science
    • Nodejs Tutorial
  • Blog
  • Contact us
  • Toggle search form
Build a ChatGPT Clone using MERN Stack

Build a ChatGPT Clone using MERN Stack

Posted on March 13, 2026March 13, 2026 By Updategadh No Comments on Build a ChatGPT Clone using MERN Stack

Build Your Build a ChatGPT Clone?

Everyone uses ChatGPT — but almost no student has built one. That’s exactly what makes this project stand out in your final year viva, your resume, and your GitHub. In this post, you’ll build a fully working ChatGPT Clone using MERN Stack — React.js on the frontend, Node.js + Express on the backend, MongoDB for storing chat history, and the OpenAI GPT-3.5 API as the brain.

▶ Subscribe on YouTube: DecodeIT2

Project tutorials, coding guides & placement tips for students.

This is not a toy project. It includes real-time streaming responses, conversation history, user authentication, and a clean UI that looks just like ChatGPT. Whether you’re a BCA, MCA, or B.Tech CS student — this is the project that will get you noticed.

Also Explore These Popular Projects on UpdateGadh:

  • AI Chat Bot Using Python + Flask
  • AI Assistant Using Python + OpenAI
  • MERN Stack Projects with Source Code
  • Face Recognition Attendance System
  • Top 10 Real-Time Python Projects 2026

Project Overview

Project NameChatGPT Clone
FrontendReact.js + Tailwind CSS
BackendNode.js + Express.js
DatabaseMongoDB + Mongoose
AI EngineOpenAI GPT-3.5 Turbo API
AuthenticationJWT + bcrypt
DifficultyIntermediate
Best ForBCA, MCA, B.Tech CS/IT Final Year Students

Key Features

  • Real-time AI responses using OpenAI GPT-3.5 Turbo
  • Conversation history saved per user in MongoDB
  • Create new chats and switch between old conversations
  • User registration and login with JWT authentication
  • Markdown rendering for code blocks and formatted answers
  • Responsive UI — works on mobile and desktop
  • Delete individual conversations
  • Sidebar with all previous chats like the real ChatGPT

Technologies Used

LayerTechnologyPurpose
FrontendReact.jsInteractive chat UI with component-based structure
StylingTailwind CSSClean, responsive design system
BackendNode.js + Express.jsREST API server handling all routes
AIOpenAI GPT-3.5 TurboGenerate intelligent chat responses
DatabaseMongoDB + MongooseStore users and conversation history
AuthJWT + bcryptSecure login and session management
HTTP ClientAxiosFrontend-to-backend API calls
Markdownreact-markdownRender formatted AI responses with code blocks

Project Folder Structure

chatgpt-clone/
│
├── backend/
│   ├── server.js
│   ├── .env
│   ├── config/
│   │   └── db.js
│   ├── models/
│   │   ├── User.js
│   │   └── Conversation.js
│   ├── routes/
│   │   ├── authRoutes.js
│   │   └── chatRoutes.js
│   ├── controllers/
│   │   ├── authController.js
│   │   └── chatController.js
│   └── middleware/
│       └── authMiddleware.js
│
└── frontend/
    ├── public/
    ├── src/
    │   ├── App.jsx
    │   ├── main.jsx
    │   ├── components/
    │   │   ├── Sidebar.jsx
    │   │   ├── ChatWindow.jsx
    │   │   ├── MessageBubble.jsx
    │   │   └── InputBar.jsx
    │   ├── pages/
    │   │   ├── Login.jsx
    │   │   ├── Register.jsx
    │   │   └── Chat.jsx
    │   ├── context/
    │   │   └── AuthContext.jsx
    │   └── api/
    │       └── axios.js
    └── package.json
Build a ChatGPT Clone using MERN Stack
Build a ChatGPT Clone using MERN Stack

Full Source Code

1. Backend — server.js

const express = require('express');
const cors = require('cors');
const dotenv = require('dotenv');
const connectDB = require('./config/db');

dotenv.config();
connectDB();

const app = express();
app.use(cors());
app.use(express.json());

app.use('/api/auth', require('./routes/authRoutes'));
app.use('/api/chat', require('./routes/chatRoutes'));

const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));

2. Backend — config/db.js

const mongoose = require('mongoose');

const connectDB = async () => {
  try {
    await mongoose.connect(process.env.MONGO_URI);
    console.log('MongoDB Connected');
  } catch (error) {
    console.error(error.message);
    process.exit(1);
  }
};

module.exports = connectDB;

3. Backend — models/User.js

const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');

const UserSchema = new mongoose.Schema({
  name:     { type: String, required: true },
  email:    { type: String, required: true, unique: true },
  password: { type: String, required: true },
}, { timestamps: true });

UserSchema.pre('save', async function (next) {
  if (!this.isModified('password')) return next();
  this.password = await bcrypt.hash(this.password, 10);
  next();
});

UserSchema.methods.matchPassword = async function (enteredPassword) {
  return await bcrypt.compare(enteredPassword, this.password);
};

module.exports = mongoose.model('User', UserSchema);

4. Backend — models/Conversation.js

const mongoose = require('mongoose');

const MessageSchema = new mongoose.Schema({
  role:    { type: String, enum: ['user', 'assistant'], required: true },
  content: { type: String, required: true },
});

const ConversationSchema = new mongoose.Schema({
  user:     { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
  title:    { type: String, default: 'New Chat' },
  messages: [MessageSchema],
}, { timestamps: true });

module.exports = mongoose.model('Conversation', ConversationSchema);

5. Backend — controllers/authController.js

const User = require('../models/User');
const jwt  = require('jsonwebtoken');

const generateToken = (id) =>
  jwt.sign({ id }, process.env.JWT_SECRET, { expiresIn: '7d' });

exports.register = async (req, res) => {
  const { name, email, password } = req.body;
  try {
    const exists = await User.findOne({ email });
    if (exists) return res.status(400).json({ message: 'Email already registered' });
    const user = await User.create({ name, email, password });
    res.status(201).json({ token: generateToken(user._id), name: user.name });
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
};

exports.login = async (req, res) => {
  const { email, password } = req.body;
  try {
    const user = await User.findOne({ email });
    if (!user || !(await user.matchPassword(password)))
      return res.status(401).json({ message: 'Invalid credentials' });
    res.json({ token: generateToken(user._id), name: user.name });
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
};

6. Backend — controllers/chatController.js

const OpenAI       = require('openai');
const Conversation = require('../models/Conversation');

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

// Send message and get AI response
exports.sendMessage = async (req, res) => {
  const { conversationId, message } = req.body;
  const userId = req.user.id;

  try {
    let conversation;

    if (conversationId) {
      conversation = await Conversation.findById(conversationId);
    } else {
      conversation = await Conversation.create({
        user: userId,
        title: message.slice(0, 40),
        messages: [],
      });
    }

    // Add user message
    conversation.messages.push({ role: 'user', content: message });

    // Build context (last 10 messages)
    const context = conversation.messages.slice(-10).map(m => ({
      role: m.role,
      content: m.content,
    }));

    // Call OpenAI
    const completion = await openai.chat.completions.create({
      model: 'gpt-3.5-turbo',
      messages: [
        { role: 'system', content: 'You are a helpful AI assistant.' },
        ...context,
      ],
    });

    const reply = completion.choices[0].message.content;

    // Save AI response
    conversation.messages.push({ role: 'assistant', content: reply });
    await conversation.save();

    res.json({ reply, conversationId: conversation._id });
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
};

// Get all conversations for sidebar
exports.getConversations = async (req, res) => {
  try {
    const convos = await Conversation.find({ user: req.user.id })
      .select('title createdAt')
      .sort({ createdAt: -1 });
    res.json(convos);
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
};

// Get single conversation messages
exports.getConversation = async (req, res) => {
  try {
    const convo = await Conversation.findById(req.params.id);
    if (!convo) return res.status(404).json({ message: 'Not found' });
    res.json(convo);
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
};

// Delete conversation
exports.deleteConversation = async (req, res) => {
  try {
    await Conversation.findByIdAndDelete(req.params.id);
    res.json({ message: 'Deleted' });
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
};

7. Backend — middleware/authMiddleware.js

const jwt  = require('jsonwebtoken');
const User = require('../models/User');

const protect = async (req, res, next) => {
  let token = req.headers.authorization?.split(' ')[1];
  if (!token) return res.status(401).json({ message: 'Not authorized' });
  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = await User.findById(decoded.id).select('-password');
    next();
  } catch {
    res.status(401).json({ message: 'Token invalid' });
  }
};

module.exports = protect;

8. Backend — routes/authRoutes.js

const express  = require('express');
const router   = express.Router();
const { register, login } = require('../controllers/authController');

router.post('/register', register);
router.post('/login',    login);

module.exports = router;

9. Backend — routes/chatRoutes.js

const express  = require('express');
const router   = express.Router();
const protect  = require('../middleware/authMiddleware');
const {
  sendMessage, getConversations,
  getConversation, deleteConversation
} = require('../controllers/chatController');

router.post('/',                          protect, sendMessage);
router.get('/conversations',              protect, getConversations);
router.get('/conversations/:id',          protect, getConversation);
router.delete('/conversations/:id',       protect, deleteConversation);

module.exports = router;

10. Backend — .env

MONGO_URI=mongodb://localhost:27017/chatgpt-clone
JWT_SECRET=your_secret_key_here
OPENAI_API_KEY=sk-proj-your-openai-key-here
PORT=5000

11. Frontend — src/api/axios.js

import axios from 'axios';

const instance = axios.create({ baseURL: 'https://updategadh.com/api' });

instance.interceptors.request.use((config) => {
  const token = localStorage.getItem('token');
  if (token) config.headers.Authorization = `Bearer ${token}`;
  return config;
});

export default instance;

12. Frontend — src/pages/Chat.jsx (Main Chat Page)

import { useState, useEffect, useRef } from 'react';
import axios from '../api/axios';
import Sidebar from '../components/Sidebar';
import MessageBubble from '../components/MessageBubble';
import InputBar from '../components/InputBar';

export default function Chat() {
  const [conversations, setConversations]   = useState([]);
  const [activeConvoId, setActiveConvoId]   = useState(null);
  const [messages, setMessages]             = useState([]);
  const [loading, setLoading]               = useState(false);
  const bottomRef                           = useRef(null);

  useEffect(() => { fetchConversations(); }, []);
  useEffect(() => { bottomRef.current?.scrollIntoView({ behavior: 'smooth' }); }, [messages]);

  const fetchConversations = async () => {
    const res = await axios.get('/chat/conversations');
    setConversations(res.data);
  };

  const loadConversation = async (id) => {
    setActiveConvoId(id);
    const res = await axios.get(`/chat/conversations/${id}`);
    setMessages(res.data.messages);
  };

  const sendMessage = async (text) => {
    const userMsg = { role: 'user', content: text };
    setMessages(prev => [...prev, userMsg]);
    setLoading(true);

    const res = await axios.post('/chat', {
      message: text,
      conversationId: activeConvoId,
    });

    setMessages(prev => [...prev, { role: 'assistant', content: res.data.reply }]);
    setActiveConvoId(res.data.conversationId);
    setLoading(false);
    fetchConversations();
  };

  const newChat = () => { setActiveConvoId(null); setMessages([]); };

  const deleteConvo = async (id) => {
    await axios.delete(`/chat/conversations/${id}`);
    if (id === activeConvoId) newChat();
    fetchConversations();
  };

  return (
    <div className="flex h-screen bg-gray-900 text-white">
      <Sidebar
        conversations={conversations}
        activeId={activeConvoId}
        onSelect={loadConversation}
        onNew={newChat}
        onDelete={deleteConvo}
      />
      <div className="flex flex-col flex-1">
        <div className="flex-1 overflow-y-auto p-6 space-y-4">
          {messages.length === 0 && (
            <div className="flex items-center justify-center h-full text-gray-400 text-xl">
              How can I help you today?
            </div>
          )}
          {messages.map((msg, i) => (
            <MessageBubble key={i} role={msg.role} content={msg.content} />
          ))}
          {loading && (
            <div className="text-gray-400 animate-pulse">ChatGPT is thinking...</div>
          )}
          <div ref={bottomRef} />
        </div>
        <InputBar onSend={sendMessage} disabled={loading} />
      </div>
    </div>
  );
}

13. Frontend — src/components/Sidebar.jsx

export default function Sidebar({ conversations, activeId, onSelect, onNew, onDelete }) {
  return (
    <div className="w-64 bg-gray-800 flex flex-col p-3 gap-2">
      <button
        onClick={onNew}
        className="bg-gray-700 hover:bg-gray-600 rounded-lg p-3 text-sm font-medium"
      >
        + New Chat
      </button>
      <div className="flex-1 overflow-y-auto space-y-1 mt-2">
        {conversations.map(c => (
          <div
            key={c._id}
            onClick={() => onSelect(c._id)}
            className={`flex justify-between items-center p-2 rounded-lg cursor-pointer text-sm
              ${activeId === c._id ? 'bg-gray-600' : 'hover:bg-gray-700'}`}
          >
            <span className="truncate">{c.title}</span>
            <button
              onClick={(e) => { e.stopPropagation(); onDelete(c._id); }}
              className="text-gray-400 hover:text-red-400 ml-2"
            >✕</button>
          </div>
        ))}
      </div>
    </div>
  );
}

14. Frontend — src/components/MessageBubble.jsx

import ReactMarkdown from 'react-markdown';

export default function MessageBubble({ role, content }) {
  const isUser = role === 'user';
  return (
    <div className={`flex ${isUser ? 'justify-end' : 'justify-start'}`}>
      <div className={`max-w-2xl px-4 py-3 rounded-2xl text-sm leading-relaxed
        ${isUser
          ? 'bg-blue-600 text-white rounded-br-sm'
          : 'bg-gray-700 text-gray-100 rounded-bl-sm'}`}
      >
        <ReactMarkdown>{content}</ReactMarkdown>
      </div>
    </div>
  );
}

15. Frontend — src/components/InputBar.jsx

import { useState } from 'react';

export default function InputBar({ onSend, disabled }) {
  const [text, setText] = useState('');

  const handleSend = () => {
    if (!text.trim() || disabled) return;
    onSend(text.trim());
    setText('');
  };

  const handleKey = (e) => {
    if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSend(); }
  };

  return (
    <div className="p-4 border-t border-gray-700 flex gap-3">
      <textarea
        value={text}
        onChange={e => setText(e.target.value)}
        onKeyDown={handleKey}
        placeholder="Send a message..."
        rows={1}
        className="flex-1 bg-gray-700 text-white rounded-xl px-4 py-3 resize-none outline-none text-sm"
      />
      <button
        onClick={handleSend}
        disabled={disabled || !text.trim()}
        className="bg-blue-600 hover:bg-blue-500 disabled:opacity-40 px-5 rounded-xl text-sm font-medium"
      >
        Send
      </button>
    </div>
  );
}

How to Run This Project

Step 1 — Install Backend Dependencies

cd backend
npm install express mongoose dotenv cors bcryptjs jsonwebtoken openai

Step 2 — Install Frontend Dependencies

cd frontend
npm install
npm install axios react-markdown

Step 3 — Add Your .env File

Create the .env file inside the backend folder and fill in your MongoDB URI and OpenAI API Key.

Step 4 — Start the Backend

cd backend
node server.js

Step 5 — Start the Frontend

cd frontend
npm run dev

Open https://updategadh.com in your browser. Register an account, start chatting, and your conversations will be saved automatically!

API Endpoints Reference

MethodEndpointDescriptionAuth
POST/api/auth/registerRegister a new userNo
POST/api/auth/loginLogin and receive JWTNo
POST/api/chatSend message, get AI replyYes
GET/api/chat/conversationsGet all conversations for sidebarYes
GET/api/chat/conversations/:idLoad a specific conversationYes
DELETE/api/chat/conversations/:idDelete a conversationYes

Why This is a Perfect Final Year Project

  • Massive wow factor — you built a working clone of the world’s most popular AI tool
  • Full MERN Stack — React, Node, Express, MongoDB all in one project
  • Real OpenAI API integration — shows you can work with production AI services
  • JWT Authentication — industry-standard security that interviewers love
  • Persistent conversation history — real database design and data modeling
  • Easy to extend — add image generation, voice input, GPT-4, or custom models
  • GitHub-ready — impressive portfolio project that recruiters will notice

You Might Also Like These Projects on UpdateGadh:

  • AI Chat Bot Using Python + Flask + NLP
  • AI Assistant Using Python + OpenAI
  • Voice Assistant Using Python
  • Face Recognition Attendance System using Django
  • Heart Disease Risk Prediction using Machine Learning
  • Top 10 Real-Time Python Projects 2026

Post Views: 108
React Projects Tags:chatgpt clone apk, chatgpt clone github nextjs, chatgpt clone github python, chatgpt clone html, chatgpt clone source code, chatgpt clone website, chatgpt-clone github, Css, how to clone chatgpt

Post navigation

Previous Post: How to Build an AI Chatbot Using OpenAI and Streamlit
Next Post: Top 10 AI Tools Every CS Student Must Use

More Related Articles

Library Management System Using MERN stack Best Library Management System Using MERN stack React Projects
Inventory Management System Best Full Stack Inventory Management System React Projects
Food Waste Reduction System – React, Java Servlets, JSP, MySQL Best Food Waste Reduction System – React, Java Servlets, JSP, MySQL React Projects

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

You may also like

  1. Best Contact Management System Using Node.js, Express, MongoDB
  2. Best AI-Powered Real Estate Management System Using MERN Stack
  3. Best Health Insurance Management System MERN Stack
  4. Best Full Stack Inventory Management System
  5. Best leave Management System Using MERN-Based Web Application
  6. Best Online Book Store Using Django and React

Most Viewed Posts

  1. Top Large Language Models in 2025
  2. Online Shopping System using PHP, MySQL with Free Source Code
  3. login form in php and mysql , Step-by-Step with Free Source Code
  4. Flipkart Clone using PHP And MYSQL Free Source Code
  5. News Portal Project in PHP and MySql Free Source Code
  6. User Login & Registration System Using PHP and MySQL Free Code
  7. Top 10 Final Year Project Ideas in Python
  8. Online Bike Rental Management System Using PHP and MySQL
  9. E learning Website in php with Free source code
  10. E-Commerce Website Project in Java Servlets (JSP)
  • AI
  • ASP.NET
  • Blockchain
  • ChatCPT
  • code Snippets
  • Collage Projects
  • Data Science Project
  • Data Science Tutorial
  • DBMS Tutorial
  • Deep Learning Tutorial
  • Final Year Projects
  • Free Projects
  • How to
  • html
  • Interview Question
  • Java Notes
  • Java Project
  • Java Script Notes
  • JAVASCRIPT
  • Javascript Project
  • JSP JAVA(J2EE)
  • Machine Learning Project
  • Machine Learning Tutorial
  • MySQL Tutorial
  • Node.js Tutorial
  • PHP Project
  • Portfolio
  • Python
  • Python Interview Question
  • Python Projects
  • PythonFreeProject
  • React Free Project
  • React Projects
  • Spring boot
  • SQL Tutorial
  • TOP 10
  • Uncategorized
  • Online Examination System in PHP with Source Code
  • AI Chatbot for College and Hospital
  • Job Portal Web Application in PHP MySQL
  • Online Tutorial Portal Site in PHP MySQL — Full Project with Source Code
  • Online Job Portal System in JSP Servlet MySQL

Most Viewed Posts

  • Top Large Language Models in 2025 (8,614)
  • Online Shopping System using PHP, MySQL with Free Source Code (5,215)
  • login form in php and mysql , Step-by-Step with Free Source Code (4,868)

Copyright © 2026 UpdateGadh.

Powered by PressBook Green WordPress theme