Welcome to FullStack. We use cookies to enable better features on our website. Cookies help us tailor content to your interests and locations and provide other benefits on the site. For more information, please see our Cookies Policy and Privacy Policy.
Creating new applications using React and Node.js always requires a certain amount of work before you actually start working on the final solution. In this tutorial you will find everything you need to start from scratch.
Start with the basics
*Note: Prior to starting working with this tutorial you must have at least Node.js 10 or higher installed on your machine. You can find the installation guide here
Installing Node.js dependencies
First, we're going to use Express as the API that will handle every request made by the front-end:
npm --save express
Now that we have installed our core library we can proceed to create the Node file that will execute all the logic of our application. Create a server.js File in the root directory of your back-end project:
Inside server.js place the following code:
var app = require('express')();
var http = require('http').createServer(app);
const PORT = 8080;
http.listen(PORT, () => {
console.log(`listening on *:${PORT}`);
});
Now that you have placed the code inside server.js, let’s quickly make sure everything is working by running the following command:
node server.js
If everything is in order, the message “listening on *:8080” should appear in the console.
Socket.IO
Now we can proceed to install the library which can handle the web sockets connections:
npm i --save socket.io
Let’s create our first socket listener in the server.js file:
var app = require('express')();
var http = require('http').createServer(app);
const PORT = 8080;
var io = require('socket.io')(http);
http.listen(PORT, () => {
console.log(`listening on *:${PORT}`);
});
io.on('connection', (socket) => { /* socket object may be used to send specific messages to the new connected client */console.log('new client connected');
});
Creating the Front End
The first step to create the front end of our applications will be to initialize the React application. You can easily do this with the command:
npx create-react-app my-app
Now that the code base is initialized, we can proceed to install the Socket.IO library for our front end. Just use the client library of socket.io with:
npm i socket.io-client
Connecting the client with the server
If this is your first time using Socket.IO, this part will be exciting since we are enabling real-time communication between a single client and our back end using web sockets. In the ~/App.js include the Socket.IO client and create a variable to store the socket object like this:
import React from'react';import logo from'./logo.svg';import'./App.scss';import socketClient from"socket.io-client";
const SERVER = "http://127.0.0.1:8080";
functionApp() {
var socket = socketClient (SERVER);
return (
<divclassname="App"></div><headerclassname="App-header"></header><imgsrc="{logo}"classname="App-logo"alt="logo"><p></p> Edit <code>src/App.js</code> and save to reload.
<p></p>
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
);
}
export default App;
Now that we have our socket variable, we can start listening to events emitted by our back end. In order to be notified when the client is connected we have to tweak our previous code in the server.js file:
var app = require('express')();
var http = require('http').createServer(app);
const PORT = 8080;
var io = require('socket.io')(http);
const STATIC_CHANNELS = ['global_notifications', 'global_chat'];
http.listen(PORT, () => {
console.log(`listening on *:${PORT}`);
});
io.on('connection', (socket) => { /* socket object may be used to send specific messages to the new connected client */console.log('new client connected');
socket.emit('connection', null);
});
With the socket.emit function, custom events can be sent from the back end to the front end through the newly established socket connection. This method will only send messages between the specific client that was recently connected. Sending messages to all the clients connected will be explained later.
In order to receive those notifications from the back end, we need to listen for the events created there. For example, we are emitting the connection event to the client as soon it opens a new connection, so we have to put the same label in our front to execute some code when this happens:
var socket = socketClient (SERVER);
socket.on('connection', () => {
console.log(`I'm connected with the back-end`);
});
In the browser it should look like this:
Building the chat
With the installation complete, we can focus on building the UI of our application and the logic behind it.
In order to create a standalone components, we have to create a folder called “chat” with the following structure:
import React from'react';import { Channel } from'./Channel';
exportclassChannelListextendsReact.Component{
render() {
let list = `There is no channels to show`;
if (this.props.channels) {
list = this.props.channels.map(c =><channelkey="{c.id}"id="{c.id}"name="{c.name}"participants="{c.participants}">);</channel> }
return (
<divclassname="channel-list"></div>
{list}
);
}
}
To see the chat as a full window component, you might want to stylize the root element to fill the whole screen. To do so, you will have to modify the index.css file and add this:
At this point the application should look something like this
Now that we have an interface structure, we might want to define the messages panel. For this, we have to create a new component called MessagesPane.js and Message.js.
With the code above the information for the channels should be displayed in the application like this:
You are now connected with the back end via websocket and http. For real time communication, we have to define some listeners and emit some events in order to update the information of every channel. Selecting a channel should trigger an event that the back end will handle.
The front end needs to handle these events as well. To capture the events we have to use the same event name that the back end emits and vice versa. When the client hits the channel, an event must be sent to the back end to calculate the number of participants and broadcast to all the current sockets that a new user entered the channel.
io.on('connection', (socket) => { // socket object may be used to send specific messages to the new connected clientconsole.log('new client connected');
socket.emit('connection', null);
socket.on('channel-join', id => {
console.log('channel join', id);
STATIC_CHANNELS.forEach(c => {
if (c.id === id) {
if (c.sockets.indexOf(socket.id) == (-1)) {
c.sockets.push(socket.id);
c.participants++;
io.emit('channel', c);
}
} else {
let index = c.sockets.indexOf(socket.id);
if (index != (-1)) {
c.sockets.splice(index, 1);
c.participants--;
io.emit('channel', c);
}
}
});
return id;
})
});
With this logic implemented, the application now captures the events emitted from the client and the server.
Sending Messages
It’s time to start sending some specific messages over the websocket. To accomplish this, we have to capture the information in our textbox and then submit it by clicking the send button. When the click event is captured, we have to make sure that we can send all the information related to the message. In this case the information will be:
senderName: The id of the socket sending the message.
id: The id of the message which is going to be the current timestamp.
text: The text captured in the input.
channel_id: The id of the channel where the message was sent to.
Here at FullStack Labs, our UI/UX designers, React developers, and Node.js developers all follow a playbook and apply coding best practices such as those found here. The previous guide was intended only to explain a simple way to communicate between the front end and the back end of a single application and makes no claim as to best practices around React nor Node development.
What technologies are used to build this chat application?
This tutorial uses:
React – to build the front-end interface
Express.js – to create the server and handle API requests
Socket.IO – to enable real-time, bidirectional communication between clients and the server
Node.js – as the runtime environment powering the backend
Together, these tools allow you to build a responsive, real-time chat app from scratch.
How does Socket.IO make real-time messaging possible?
Socket.IO sets up a persistent connection between the client and the server, allowing data to move back and forth instantly. Whenever a user connects, joins a channel, or sends a message, Socket.IO ensures that every connected client gets the update right away — no constant polling or reloads needed.
How does the app handle multiple chat channels?
Each channel is tracked on the backend, including its participant count and activity. When a user joins a channel, the server updates that channel’s data and shares the changes with every connected client. This way, everyone sees the same live participant counts and messages, keeping the app synchronized in real time.
How are messages sent and displayed to other users?
When a user sends a message, the app collects key details like the sender’s ID, the message text, the channel it belongs to, and a timestamp. That data is sent to the server, which immediately broadcasts the message to every client in that channel. The UI updates instantly, so everyone in the conversation sees the new message appear without delay.
How do the front end and back end communicate?
The app uses a mix of standard API requests and real-time WebSocket events. For example, it fetches the list of available chat channels through the getChannels endpoint, but joining channels, updating participant counts, and sending messages all happen through Socket.IO events for seamless, live updates.
AI is changing software development.
The Engineer's AI-Enabled Development Handbook is your guide to incorporating AI into development processes for smoother, faster, and smarter development.
Enjoyed the article? Get new content delivered to your inbox.
Subscribe below and stay updated with the latest developer guides and industry insights.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.