Create Masonry Layout in React Using react-masonry-component

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-demo

Step 2: Install react-masonry-component

Next, install the library:

npm install react-masonry-component

This 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.

react-masonry-component
  • 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.

Masonry Layout in React

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.

Create Masonry Layout in React

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.

Create Masonry Layout in React Using react-masonry-component

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)

  1. Images overlapping:
    Ensure each image has a fixed width or is contained within the same width container.
  2. Layout not updating on new data:
    Use the updateOnEachImageLoad prop set to true.
  3. 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:

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.