React-React photo gallery 8.0.0: React Photo Gallery

Latest Release: 8.0.0
  • Gallery uses React.memo
  • Use hooks
  • Update examples
  • Update tests
  • Bump default limitNodeSearch to 2
  • Change the way renderImage works. You now need to pass in your own key. The component is no longer wrapped in a div with a key.

Possible breaking changes

  • if your are using a custom component (renderImage prop), you may get a warning about keys. It could also stop interacting correctly with other libraries that use an HOC.
  • the Gallery uses React.memo. That means it does a shallow update of props. If you are mutating your photos array directly, it will no longer trigger a change. You will need to make sure your prop values are immutable if you want them to trigger Gallery updates.
Source code(tar.gz)
Source code(zip)

React Photo Gallery

Join the chat at npm version npm downloads Build Status Coverage Status Dependency Status

  • Responsive, accessible, composable, and customizable image gallery component
  • Maintains the original aspect ratio of your photos
  • Creates a masonry or justified grid
  • Supports row or column direction layout
  • Provides an image renderer for custom implementation of things like image selection, favorites, captions, etc.
  • SSR app compatible


Row Column


yarn add react-photo-gallery

API Documentation

CodeSandbox Demos with Example Use Cases

To build some examples locally, git clone and run:

yarn install
yarn start

Then open localhost:8000 in a browser.

Minimal Setup Example

const photos = [
    src: '',
    width: 4,
    height: 3
    src: '',
    width: 1,
    height: 1

<Gallery photos={photos} />;

How It Works

Row Layout

This layout uses an algorithm adapted from the Knuth and Plass line breaking algorithm. It uses a graph to calculate the single best layout where each photo to break on is represented by a node and each edge is represented by a row. The cost of the edge is determined by the user provided targetRowHeight vs the row height calculated if it were to break on this node/photo. What you end up with is a layout with rows that are similar in height and photos that are not being stretched or shrunken abnormally as is what happens in a naive implementation. This solves the issue of panoramas shrinking rows or having stragglers or stretched images at the last row, instead creating a justified grid. To make sure it's speedy the graph is being built as the shortest path is being calculated so the entire adjacency list is not calculated ahead of time. You can control how many neighboring nodes that Dijkstra's algorithm will search when it's visiting a node by adjusting the limitNodeSearch property, but it's recommended you use the default algorithm. See documentation for recommendations.

Inspired by this blog article and this Google Photos blog article (under 2. Justified Gallery).

Column Layout

Goes through each column looking for the best place to insert the next photo by finding the shortest column. Not recommended for panorama aspect ratios.


Special thanks to Christopher Chedeau for writing about this interesting algorithm and whos code served as a starting off point.


  • Adding attributes
    Adding attributes

    Jul 3, 2021

    Is there a way to add attributes to each image element so that we can use animate on scroll?

  • Handing images when they are missing
    Handing images when they are missing

    Jul 8, 2021

    Is there a way to handle an image when its missing? Either changing the opacity? I can add a placeholder but can i add specific css to this image such as opacity?


  • Empty markup rendered using Jest and testing-library
    Empty markup rendered using Jest and testing-library

    Aug 16, 2021


    I've tried to test my gallery component which is customized a bit, and I wasn't able to create correct snapshot with Jest and @testing-library/react. I was struggling and thinking that there's something wrong with my code, but finally I've created very simple reproduction repo that shows that there's something wrong with generating snapshots:

    Could you point me to the right direction with this?

  • React 17.x support
    React 17.x support

    Aug 24, 2021

    It would be really cool if this library supported React version 17 and up. I tried pulling the project myself to see if I could get it working with V17 but the errors I am getting are far over my head.. It seems like 3 or 4 of the peer dependencies of other modules needed for this library are conflicting with the versions installed in this library as well.

  • Images become stretchy vertically  on iPhone Safari
    Images become stretchy vertically on iPhone Safari

    Oct 19, 2021

    Images become stretchy vertically on iPhone Safari

  • How to load many images locally
    How to load many images locally

    Oct 25, 2021

    I'm trying to figure out how to load many images locally in the gallery without import them one by one... in fact idk if that would be possible... appreciate any help on that!

  • #205 support for react 17
    #205 support for react 17

    Nov 7, 2021

    Added support for React 17. Apologies for the replacement of single quotes with double quotes - I forgot that I played around with some vim settings a while ago and didn't notice til just now. Only a few superfluous edits due to that though.

    All tests pass though with some warnings about writing directly to the DOM.

    When I do npm start and launch latest Chrome (Version 95.0.4638.69) to snoop around resizing looks outwardly fine. I use node 16.13.0 and npm 8.1.0 on a ubuntu box to build and test.

  • This Does not have support for react 17.0
    This Does not have support for react 17.0

    Dec 4, 2021

    Can't import this package while running react 17. Please update for npm installs

  • Additional props for photo
    Additional props for photo

    Dec 8, 2021

    I'd like to pass some extra properties for my photo into renderImage function. The renderImage accepts props of type

    RenderImageProps<CustomPhotoProps extends object = {}>

    but if I try to define my renderImage method like this:

    const imageRenderer: React.FC<RenderImageProps<CustomImageProps> = ({ photo, index }) => { ... }

    I get the error from Gallery component that renderImage function has incompatible props. What is the proper way to pass additional props to renderImage function?

  • Is is possible to cover images in gridview?
    Is is possible to cover images in gridview?

    Jan 11, 2022

    PhotoGallery stretches the image to show it. Can I crop the image without stretching it? Like setting the value of cover in the object-fit property.

  • Stateless gallery
    Stateless gallery

    Feb 27, 2017

    related to issue #13 and issue #20

  • Extract breakpointsConfig as separate prop with default value
    Extract breakpointsConfig as separate prop with default value

    Aug 15, 2018

    Extracted breakpoints configuration as a separate prop in order to be able to modify it.

  • Combination of sort and selection (onClick) possible?
    Combination of sort and selection (onClick) possible?

    May 22, 2018

    Tried to combine the 2 featured examples:

    • SortablePhoto
    • SelectImage

    I managed to pass an onClick handler to the example "SelectImage"):

    const SortableGallery = SortableContainer(({photos}) => { return <Gallery photos={photos} ImageComponent={SortablePhoto}/> });

    changed to by adding the propertie 'onClick':

    const SortableGallery = SortableContainer(({photos,onClick}) => { return <Gallery photos={photos} onClick={onClick} ImageComponent={SortablePhoto}/> });

    Option "pressDelay" is used to get an onClick event fired.

    However, in SelectedImage this properties are not available: index and photo (the onClick funtion passed has the the 2 parameters index and photo not available because the are not passed to the component).

    Any ideas (is it possible at all) to combine the 2 features (selection and sort)?

    Best regards

  • Grid is broken in version 5.3.0 on NPM
    Grid is broken in version 5.3.0 on NPM

    Mar 10, 2017


    Hi Sandra,

    I just upgraded from 5.0.2" to ^5.2.0" on NPM and noticed that the grid is now broken.

    Here's what it looks like using random images on Unsplash.


    After downgrading to "react-photo-gallery": "5.0.2",, the images look back to normal:

    screen shot 2017-03-10 at 4 50 11 pm

    Secondarily, the versions on Github don't sync with the versions on NPM making this issue a bit more difficult to bisect/debug.


    $ cat node_modules/react-photo-gallery/package.json | grep gitHead

    "gitHead": "51613a4ef2da6c5885e9027abc85a9aea0cd1e42",

  • Added typescript declarations
    Added typescript declarations

    Jan 18, 2019

    Hello, I've made typescript declaration files. They should be already ok, but I'll correct them if/when I/somebody else notice some missed detail.

    WHY: Needed for myself :)

    It's important not just for typescript users - they also add really nice documentation JSDoc documentation for any VSCode user :)

    Also - fixes this:

    HOW Added as external types/react-photo-gallery.d.ts file. I think index.d.ts in dist dir would have marginally better suport but I would rather not touch your nps build chain.

    I can PR them to DefinitelyTyped if you prefer to not deal with declaration file yourself, but current trend seems to be collocation with repos.


  • Routing support?
    Routing support?

    Jul 21, 2016

    Hi @neptunian! Thank you for the component!

    Do you have thoughts on the component allowing for router support - to have it update the url as one opens the lightbox and moves from one image to another?

    I noticed you are also the maintainer of react-images now. Would that be a more appropriate library to build this feature on?

    Thank you!

  • layout breaks when at certain breakpoints
    layout breaks when at certain breakpoints

    Aug 21, 2017

    caused by browser returning the containing element of gallery's width as for example 1200px when its actually 1199.5px in the computed output. since i cannot force it to round down before it is returned to me i subtract one pixel for prevention.

  • Another -> Uncaught Error: Maximum update depth exceeded
    Another -> Uncaught Error: Maximum update depth exceeded

    Apr 12, 2018

    In my application I needed to create an album with one picture ( album cover ) but I came across this issue


    This error appears when the number of uploaded images is equal or less than the number of columns in the code (3 by default) <Gallery photos={photos} onClick={this.openLightbox} columns={2}/> as long as I upload more than..say 2....or 3..more than I indicated in columns={2}.... everything works perfectly well again 2018-04-12_20-25-29

  • Gallery renders incorrectly when scrollbars are present when first loading
    Gallery renders incorrectly when scrollbars are present when first loading

    May 9, 2018

    Hello! See the screenshot for an example of the problem.

    Resizing the window after the first render fixes the problem.


  • Make extending of the last row optional
    Make extending of the last row optional

    Aug 7, 2018

    Hi all!

    Images in the last row are extended to fill all the space regardless of the columns property (only single image will keep its size). The last row looks too giant if columns value is more than 3.

    So I amended the calculation of images width in the last row in utils.js file. The default behavior hasn't been changed. But now it's possible to configure this behavior (set min count of images in the last row when it should be extended). Also I added tests for it, changed styling in several files and changed the first example in order see that problem is solved (2 images don't fill the full size anymore).

    This library is awesome, I really like it! Thank you very much! I'm using it in production and the behavior described above has become a problem for me. Could you please review this PR and provide your feedback about whether it's possible to commit my changes and publish the new version to npm?