Recently, I was working on a React dashboard for a client in Chicago where users could track their project completion in real time. I needed a custom progress bar that looked modern and fit perfectly with the app’s theme.
While React offers a few prebuilt libraries, I wanted to create a custom progress bar component from scratch, something reusable, lightweight, and easy to maintain.
In this tutorial, I’ll show you exactly how I built it, step by step, using plain React. I’ll also cover a few variations so you can adapt them easily for your own projects.
What Is a Progress Bar in React?
A progress bar visually represents how much of a task has been completed. You’ll often see it in file uploads, form submissions, or dashboards that track progress toward a goal.
In React, we can build this component using simple HTML, CSS, and props. The goal is to make it dynamic, so it automatically updates as progress changes.
Method 1 – Create a Basic React Progress Bar Component
Let’s start with a simple version. This one will display a horizontal bar that fills based on a percentage value.
Step 1: Create a New React App
If you don’t already have a React app set up, create one using the following command:
npx create-react-app react-progress-bar
cd react-progress-bar
npm startStep 2: Create the ProgressBar Component
Inside the src folder, create a new file called ProgressBar.js and add the following code:
import React from "react";
import "./ProgressBar.css";
const ProgressBar = ({ progress }) => {
return (
<div className="progress-container">
<div
className="progress-bar"
style={{ width: `${progress}%` }}
>
<span className="progress-label">{progress}%</span>
</div>
</div>
);
};
export default ProgressBar;Step 3: Add CSS Styling
Now, create a ProgressBar.css file in the same folder:
.progress-container {
width: 100%;
background-color: #e0e0e0;
border-radius: 10px;
height: 25px;
overflow: hidden;
margin: 20px 0;
}
.progress-bar {
height: 100%;
background-color: #0078d7;
text-align: center;
color: white;
font-weight: bold;
border-radius: 10px 0 0 10px;
transition: width 0.4s ease;
}
.progress-label {
position: relative;
top: 2px;
}Step 4: Use It in App.js
Open your App.js file and add the following:
import React, { useState, useEffect } from "react";
import ProgressBar from "./ProgressBar";
function App() {
const [progress, setProgress] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
setProgress((prev) => (prev >= 100 ? 100 : prev + 10));
}, 1000);
return () => clearInterval(timer);
}, []);
return (
<div style={{ width: "60%", margin: "50px auto", textAlign: "center" }}>
<h2>Project Completion Tracker</h2>
<ProgressBar progress={progress} />
</div>
);
}
export default App;You can refer to the screenshot below to see the output.

Now run your app, you’ll see a smooth animated progress bar that updates every second until it reaches 100%.
Method 2 – Add Color Variations Based on Progress
In real-world applications, it’s helpful to change the color based on progress (for example, red for low, yellow for medium, and green for high).
Here’s how you can modify the component to include color logic.
Update your ProgressBar.js file as follows:
import React from "react";
import "./ProgressBar.css";
const ProgressBar = ({ progress }) => {
const getColor = () => {
if (progress < 40) return "#d9534f"; // red
if (progress < 80) return "#f0ad4e"; // yellow
return "#5cb85c"; // green
};
return (
<div className="progress-container">
<div
className="progress-bar"
style={{
width: `${progress}%`,
backgroundColor: getColor(),
}}
>
<span className="progress-label">{progress}%</span>
</div>
</div>
);
};
export default ProgressBar;You can refer to the screenshot below to see the output.

Now your progress bar visually communicates progress levels, a small but powerful UX improvement.
Method 3 – Animated Progress Bar with React Hooks
If you want a more dynamic feel, you can add smooth animation using CSS transitions and React state updates.
Update your CSS slightly:
.progress-bar {
transition: width 0.5s ease-in-out, background-color 0.5s ease;
}Then, in your App.js, allow users to manually update progress using buttons:
import React, { useState } from "react";
import ProgressBar from "./ProgressBar";
function App() {
const [progress, setProgress] = useState(0);
const increaseProgress = () => {
setProgress((prev) => (prev >= 100 ? 100 : prev + 10));
};
const decreaseProgress = () => {
setProgress((prev) => (prev <= 0 ? 0 : prev - 10));
};
return (
<div style={{ width: "60%", margin: "50px auto", textAlign: "center" }}>
<h2>Upload Progress Tracker</h2>
<ProgressBar progress={progress} />
<button onClick={decreaseProgress} style={{ margin: "10px" }}>
Decrease
</button>
<button onClick={increaseProgress}>Increase</button>
</div>
);
}
export default App;You can refer to the screenshot below to see the output.

Now you have a fully interactive progress bar. You can easily integrate this with file uploads, surveys, or any task that reports completion status.
Method 4 – Use React Libraries (Optional)
If you prefer not to build from scratch, you can use open-source libraries like:
For example, using Material UI:
npm install @mui/material @emotion/react @emotion/styledThen use it like this:
import React from "react";
import LinearProgress from "@mui/material/LinearProgress";
import Box from "@mui/material/Box";
function App() {
return (
<Box sx={{ width: "60%", margin: "50px auto" }}>
<h2>Task Progress</h2>
<LinearProgress variant="determinate" value={65} />
</Box>
);
}
export default App;This method is ideal when you want consistent styling and accessibility out of the box.
Tips for Using Progress Bars in Real Projects
- Keep it simple: Users should instantly understand what the bar represents.
- Add labels: Always show the percentage or status text.
- Use transitions: Smooth animations make progress feel natural.
- Test responsiveness: Ensure the bar looks good on both desktop and mobile.
- Avoid overuse: Only use progress bars when the user needs feedback on a time-consuming task.
When I implemented this progress bar in my client’s dashboard, it dramatically improved user engagement. People could visually track their progress toward project goals, and that small addition made the experience much more satisfying.
So, whether you’re tracking uploads, survey completions, or project milestones, this React progress bar component is a perfect starting point.
Try building it yourself, and once you do, you’ll see how easy it is to extend it with animations, tooltips, or even circular progress indicators.
You may also like to read other React tutorials:
- Route Component in React Router
- Optional Props in React Components
- Extend Functional Components in ReactJS
- How to Create a React Header Component

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.