Build a React Chat UI Component

Recently, I was building a small project for a client where I needed to create a chat interface that looked modern, lightweight, and responsive.

The challenge was that there wasn’t a simple, ready-made example that explained how to create a React Chat UI component from scratch, one that could handle real-time messages, user avatars, and automatic scrolling.

I’ll also show you two different methods, one using pure React components and another using a React Chat UI library to speed things up.

Prerequisites

Before we start, make sure you have:

  • Node.js and npm installed
  • Basic knowledge of React (functional components, props, and state)
  • A code editor (I use VS Code)

You can check your Node version by running:

node -v
npm -v

Method 1 – Build a Chat UI Component Using Pure React

This is the method I personally prefer when I want complete control over the design and behavior of the chat interface.

Here’s how I built it step by step.

Step 1: Create a New React App

Open your terminal and run:

npx create-react-app react-chat-ui
cd react-chat-ui
npm start

This sets up a new React project and starts the development server.

Step 2: Create the Chat Component

Inside the src folder, create a new file named ChatUI.js.

Paste the following code:

import React, { useState, useEffect, useRef } from "react";
import "./ChatUI.css";

function ChatUI() {
  const [messages, setMessages] = useState([
    { sender: "bot", text: "Hi there! How can I help you today?" },
  ]);
  const [input, setInput] = useState("");
  const chatEndRef = useRef(null);

  useEffect(() => {
    chatEndRef.current?.scrollIntoView({ behavior: "smooth" });
  }, [messages]);

  const handleSend = () => {
    if (!input.trim()) return;

    const newMessage = { sender: "user", text: input };
    setMessages((prev) => [...prev, newMessage]);
    setInput("");

    // Simulate bot response
    setTimeout(() => {
      const botReply = {
        sender: "bot",
        text: "Got it! I’ll get back to you shortly.",
      };
      setMessages((prev) => [...prev, botReply]);
    }, 1000);
  };

  return (
    <div className="chat-container">
      <div className="chat-box">
        {messages.map((msg, index) => (
          <div
            key={index}
            className={`chat-message ${msg.sender === "user" ? "user" : "bot"}`}
          >
            <div className="avatar">
              {msg.sender === "user" ? "🧑" : "🤖"}
            </div>
            <div className="message-text">{msg.text}</div>
          </div>
        ))}
        <div ref={chatEndRef} />
      </div>

      <div className="chat-input">
        <input
          type="text"
          placeholder="Type your message..."
          value={input}
          onChange={(e) => setInput(e.target.value)}
          onKeyDown={(e) => e.key === "Enter" && handleSend()}
        />
        <button onClick={handleSend}>Send</button>
      </div>
    </div>
  );
}

export default ChatUI;

Step 3: Add CSS Styling

Now, create a file named ChatUI.css in the same folder.

.chat-container {
  width: 400px;
  margin: 40px auto;
  border: 1px solid #ddd;
  border-radius: 10px;
  display: flex;
  flex-direction: column;
  background-color: #fafafa;
  font-family: Arial, sans-serif;
}

.chat-box {
  flex-grow: 1;
  padding: 15px;
  overflow-y: auto;
  height: 400px;
}

.chat-message {
  display: flex;
  margin-bottom: 12px;
}

.chat-message.user {
  flex-direction: row-reverse;
}

.avatar {
  font-size: 24px;
  margin: 0 10px;
}

.message-text {
  background-color: #e0e0e0;
  padding: 10px 15px;
  border-radius: 15px;
  max-width: 70%;
}

.chat-message.user .message-text {
  background-color: #0078ff;
  color: white;
}

.chat-input {
  display: flex;
  border-top: 1px solid #ddd;
}

.chat-input input {
  flex-grow: 1;
  border: none;
  padding: 10px;
  border-radius: 0 0 0 10px;
  outline: none;
}

.chat-input button {
  background-color: #0078ff;
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 0 0 10px 0;
  cursor: pointer;
}

Step 4: Use the Component

Open App.js and replace its content with:

import React from "react";
import ChatUI from "./ChatUI";

function App() {
  return (
    <div>
      <h2 style={{ textAlign: "center" }}>React Chat UI Example</h2>
      <ChatUI />
    </div>
  );
}

export default App;

You can see the output in the screenshot below.

Build a React Chat UI Component

Now, open your browser, and you’ll see a simple, clean chat interface that supports sending messages, auto-scroll, and simulated bot replies.

Method 2 – Create a Chat UI Using a Library

If you want to save time or need advanced features like message grouping, timestamps, or typing indicators, you can use a React library like Chat UI Kit from Chatscope.

Step 1: Install the Package

npm install @chatscope/chat-ui-kit-react @chatscope/chat-ui-kit-styles

Step 2: Create a Chat Component

Create a new file ChatLibraryExample.js and add the following:

import React from "react";
import "@chatscope/chat-ui-kit-styles/dist/default/styles.min.css";
import {
  MainContainer,
  ChatContainer,
  MessageList,
  Message,
  MessageInput,
  TypingIndicator,
} from "@chatscope/chat-ui-kit-react";

function ChatLibraryExample() {
  const [messages, setMessages] = React.useState([
    { message: "Hello! How can I help you today?", sender: "ChatBot" },
  ]);
  const [typing, setTyping] = React.useState(false);

  const handleSend = (message) => {
    const newMessage = { message, sender: "User", direction: "outgoing" };
    setMessages((prev) => [...prev, newMessage]);
    setTyping(true);

    setTimeout(() => {
      setMessages((prev) => [
        ...prev,
        { message: "Sure! Let me check that for you.", sender: "ChatBot" },
      ]);
      setTyping(false);
    }, 1000);
  };

  return (
    <div style={{ position: "relative", height: "500px", width: "400px", margin: "50px auto" }}>
      <MainContainer>
        <ChatContainer>
          <MessageList typingIndicator={typing ? <TypingIndicator content="ChatBot is typing..." /> : null}>
            {messages.map((msg, i) => (
              <Message key={i} model={msg} />
            ))}
          </MessageList>
          <MessageInput placeholder="Type message here" onSend={handleSend} />
        </ChatContainer>
      </MainContainer>
    </div>
  );
}

export default ChatLibraryExample;

Step 3: Use It in Your App

In App.js, you can switch between both methods:

import React from "react";
import ChatUI from "./ChatUI";
import ChatLibraryExample from "./ChatLibraryExample";

function App() {
  return (
    <div>
      <h2 style={{ textAlign: "center" }}>React Chat UI Component Examples</h2>
      <ChatUI />
      <hr />
      <ChatLibraryExample />
    </div>
  );
}

export default App;

You can see the output in the screenshot below.

React Chat UI Component

Which Method Should You Use?

If you’re building a custom chat experience (like a support chat or AI chatbot), the pure React method gives you full control.

If you need speed and prebuilt UI elements, the Chatscope library is a great choice. It’s lightweight, responsive, and easy to style.

When I built my first chat component for a U.S. retail support dashboard, I started with the pure React version. Later, when the client requested typing indicators and message timestamps, I switched to the Chatscope library, which saved me hours of work.

That’s how you can build a clean, interactive React Chat UI component from scratch or with a library. Both methods work great; choose the one that best fits your project’s needs.

You may also like to read:

Leave a Comment

51 Python Programs

51 PYTHON PROGRAMS PDF FREE

Download a FREE PDF (112 Pages) Containing 51 Useful Python Programs.

pyython developer roadmap

Aspiring to be a Python developer?

Download a FREE PDF on how to become a Python developer.

Let’s be friends

Be the first to know about sales and special discounts.