When I first started building image-heavy dashboards in React, one of the biggest challenges I faced was organizing content in a clean, Pinterest-style grid layout.
I tried using plain CSS grid and Flexbox, but they didn’t quite give me that seamless, “waterfall” look I wanted. That’s when I discovered the react-masonry-component, and it changed everything.
In this tutorial, I’ll show you exactly how I use this library to create a beautiful, responsive Masonry layout in my React projects.
What Is a Masonry Layout?
A Masonry layout arranges elements optimally based on available vertical space. Think of the Pinterest feed; each item stacks neatly without leaving awkward gaps.
This type of layout is perfect for displaying:
- Image galleries
- Product listings
- Blog cards
- Dashboards or portfolios
In React, you can easily achieve this using the react-masonry-component library, which is a wrapper around the popular Masonry layout engine by David DeSandro.
Method 1 – Install and Set Up react-masonry-component
Before we begin, ensure you have Node.js and npm installed. Here’s how I usually set up a new React project with Masonry:
Step 1: Create a New React App
Open your terminal and run:
npx create-react-app react-masonry-demo
cd react-masonry-demoStep 2: Install react-masonry-component
Next, install the library:
npm install react-masonry-componentThis package is quite stable and works well with React 18+.
Method 2 – Create a Simple Masonry Layout
Now, let’s create our first Masonry layout. I’ll use a few sample images (you can replace them with your own). Here’s the full working code:
Full Example Code
src/App.js
import React from "react";
import Masonry from "react-masonry-component";
import "./App.css";
const masonryOptions = {
transitionDuration: 0,
gutter: 10,
};
const images = [
"https://source.unsplash.com/random/300x200?sig=1",
"https://source.unsplash.com/random/300x250?sig=2",
"https://source.unsplash.com/random/300x300?sig=3",
"https://source.unsplash.com/random/300x350?sig=4",
"https://source.unsplash.com/random/300x400?sig=5",
"https://source.unsplash.com/random/300x450?sig=6",
"https://source.unsplash.com/random/300x500?sig=7",
"https://source.unsplash.com/random/300x550?sig=8",
];
function App() {
return (
<div className="App">
<h1>My React Masonry Gallery</h1>
<Masonry
className={"my-gallery-class"}
elementType={"div"}
options={masonryOptions}
disableImagesLoaded={false}
updateOnEachImageLoad={false}
>
{images.map((src, index) => (
<div className="image-element-class" key={index}>
<img src={src} alt={`Gallery ${index}`} />
</div>
))}
</Masonry>
</div>
);
}
export default App;src/App.css
.App {
text-align: center;
padding: 20px;
background-color: #fafafa;
}
.my-gallery-class {
display: flex;
margin: auto;
justify-content: center;
}
.image-element-class {
margin-bottom: 10px;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.image-element-class img {
width: 100%;
display: block;
}I executed the above example code and added the screenshot below.

- The Masonry component automatically arranges your images in a cascading grid.
- The gutter option adds spacing between items.
- The layout adjusts dynamically as the images load.
When you run the app (npm start), you’ll see a beautiful, Pinterest-style layout in your browser.
Method 3 – Make It Responsive
By default, the Masonry layout adapts well to different screen sizes, but you can enhance responsiveness with CSS.
Here’s how I usually do it:
src/App.css (Add this below the existing CSS)
@media (max-width: 768px) {
.my-gallery-class {
display: block;
}
.image-element-class {
width: 100%;
}
}I executed the above example code and added the screenshot below.

This ensures that on smaller devices, images stack vertically for a clean mobile experience.
Method 4 – Add Dynamic Data (Optional)
You can also load images dynamically from an API, for example, from Unsplash or your own database.
Here’s a quick example using React’s useEffect and useState hooks:
import React, { useState, useEffect } from "react";
import Masonry from "react-masonry-component";
const masonryOptions = { transitionDuration: 0, gutter: 10 };
function DynamicMasonry() {
const [photos, setPhotos] = useState([]);
useEffect(() => {
fetch("https://api.unsplash.com/photos/random?count=10&client_id=YOUR_ACCESS_KEY")
.then((res) => res.json())
.then((data) => setPhotos(data))
.catch((err) => console.error(err));
}, []);
return (
<Masonry className="dynamic-gallery" options={masonryOptions}>
{photos.map((photo) => (
<div key={photo.id} className="image-element-class">
<img src={photo.urls.small} alt={photo.alt_description} />
</div>
))}
</Masonry>
);
}
export default DynamicMasonry;I executed the above example code and added the screenshot below.

This example fetches random images from Unsplash and displays them in a Masonry layout, perfect for dashboards or photo feeds.
Method 5 – Handle Image Loading Smoothly
Sometimes, images load at different speeds, which can cause layout jumps. The react-masonry-component has a built-in prop called imagesLoadedOptions that helps manage this.
Here’s how I use it:
<Masonry
className="my-gallery-class"
options={masonryOptions}
imagesLoadedOptions={{ background: ".image-element-class" }}
>
{/* image elements */}
</Masonry>I executed the above example code and added the screenshot below.

This ensures the layout updates only after all images are properly loaded, giving a smoother experience.
Bonus: Use Masonry with Material UI
If you’re already using Material UI, you can combine Masonry with MUI cards or grids for a polished look.
Example:
import { Card, CardMedia, CardContent, Typography } from "@mui/material";
import Masonry from "react-masonry-component";
function MUIStyledMasonry({ data }) {
return (
<Masonry options={{ gutter: 15 }}>
{data.map((item) => (
<Card key={item.id} sx={{ margin: "8px" }}>
<CardMedia component="img" height="200" image={item.image} alt={item.title} />
<CardContent>
<Typography variant="h6">{item.title}</Typography>
</CardContent>
</Card>
))}
</Masonry>
);
}This is great for e-commerce or portfolio websites where you want each item to have a card-like appearance.
Common Issues I’ve Encountered (and Fixed)
- Images overlapping:
Ensure each image has a fixed width or is contained within the same width container. - Layout not updating on new data:
Use the updateOnEachImageLoad prop set to true. - Performance issues with large datasets:
Lazy-load images or paginate your data to improve performance.
When I first used the react-masonry-component, it took me only a few minutes to set up, but it instantly elevated the look of my React projects.
Whether you’re building a photo gallery, a product showcase, or a portfolio, this library gives you a professional, responsive layout with minimal effort.
You may also like to read:
- How To Create a Navbar Component in React
- Difference between React Component and React Element
- Create a React Loading Spinner Component
- How to Use useRef in React Functional Components

Bijay Kumar is an experienced Python and AI professional who enjoys helping developers learn modern technologies through practical tutorials and examples. His expertise includes Python development, Machine Learning, Artificial Intelligence, automation, and data analysis using libraries like Pandas, NumPy, TensorFlow, Matplotlib, SciPy, and Scikit-Learn. At PythonGuides.com, he shares in-depth guides designed for both beginners and experienced developers. More about us.