react-image-gallery and react-photo-gallery solve distinct problems in frontend image handling. react-image-gallery is a carousel component designed for sequential viewing, offering swipe gestures, thumbnails, and fullscreen modes ideal for product showcases. react-photo-gallery focuses on responsive grid layouts, arranging images in rows or masonry styles based on aspect ratios, making it suitable for portfolios or dashboards. While both render collections of images, their underlying layout engines and interaction models differ significantly.
Both react-image-gallery and react-photo-gallery help developers display images in React applications, but they target different user experiences. One builds a slider for focused viewing, while the other builds a grid for broad overview. Understanding this core difference prevents architectural mismatches early in development. Let's compare how they handle layout, data, interaction, and maintenance.
react-image-gallery renders images in a single viewport, showing one slide at a time.
// react-image-gallery: Single viewport slider
import ImageGallery from "react-image-gallery";
const items = [
{ original: "img1.jpg", thumbnail: "thumb1.jpg" },
{ original: "img2.jpg", thumbnail: "thumb2.jpg" }
];
<ImageGallery items={items} showThumbnails={true} />
react-photo-gallery renders images in a flow layout, fitting multiple images per row.
// react-photo-gallery: Multi-image grid
import Gallery from "react-photo-gallery";
const photos = [
{ src: "img1.jpg", width: 4, height: 3 },
{ src: "img2.jpg", width: 3, height: 4 }
];
<Gallery photos={photos} margin={10} />
react-image-gallery works best with uniform or flexible image sizes.
original and thumbnail URLs.// react-image-gallery: No dimensions needed
const items = [
{ original: "https://example.com/big.jpg", thumbnail: "https://example.com/small.jpg" }
];
// Component scales automatically
<ImageGallery items={items} />
react-photo-gallery requires explicit width and height for every image.
// react-photo-gallery: Dimensions required
const photos = [
{ src: "https://example.com/img.jpg", width: 1200, height: 800 }
];
// Layout depends on accurate ratios
<Gallery photos={photos} columns={3} />
react-image-gallery provides built-in navigation controls.
// react-image-gallery: Built-in navigation
<ImageGallery
items={items}
showNav={true}
showThumbnails={true}
onClick={handleClick}
/>
react-photo-gallery focuses on click handlers for individual images.
// react-photo-gallery: Custom click handling
const handleClick = (event, photo) => {
console.log("Clicked", photo.src);
};
<Gallery photos={photos} onClick={handleClick} />
// You must implement your own modal/lightbox here
react-image-gallery has a consistent release history.
// react-image-gallery: Stable API
// Props like `onSlide`, `onPlay` remain consistent across versions
<ImageGallery items={items} onSlide={currentSlide => console.log(currentSlide)} />
react-photo-gallery has a slower update cycle.
react-grid-gallery if long-term support is critical.// react-photo-gallery: Check compatibility
// Ensure your React version matches peer dependencies
<Gallery photos={photos} />
// Verify issues page for React 18+ compatibility before adopting
While their layouts differ, both packages share common goals and patterns.
onClick and onLoad.// Both: Standard React props
<ImageGallery items={items} className="custom-gallery" />
<Gallery photos={photos} className="custom-grid" />
<img> tags under the hood.// react-image-gallery: Lazy load prop
<ImageGallery items={items} lazyLoad={true} />
// react-photo-gallery: Native lazy loading via img props
const photos = [{ src: "img.jpg", width: 4, height: 3, alt: "Desc" }];
<Gallery photos={photos} />
// Both: Custom classes
<ImageGallery className="my-slider" />
<Gallery className="my-grid" />
| Feature | react-image-gallery | react-photo-gallery |
|---|---|---|
| Layout Type | ποΈ Single Slide / Carousel | π§© Grid / Masonry |
| Data Needs | π URLs only | π Width + Height required |
| Navigation | π±οΈ Built-in arrows & swipe | π Click handlers only |
| Fullscreen | β Built-in | β Custom implementation needed |
| Maintenance | π’ Active | π‘ Slower updates |
| Best Use Case | π Product Details | π¨ Portfolios / Dashboards |
react-image-gallery is like a slideshow projector π½οΈ β perfect for guiding users through a sequence of images with minimal setup. It handles the heavy lifting of scaling and navigation, making it a safe choice for commercial products.
react-photo-gallery is like a wall of frames πΌοΈ β ideal for displaying many images at once where context matters. It requires more data preparation (dimensions) and custom work for viewing, but offers superior grid control.
Final Thought: Do not try to force a grid package to act like a slider, or vice versa. If you need sequence, pick react-image-gallery. If you need overview, pick react-photo-gallery β but verify its maintenance status fits your project timeline.
Choose react-image-gallery when you need a sequential viewing experience, such as product detail pages, hero sections, or lightboxes. It is the right fit when users need to navigate through images one by one with built-in controls like arrows, dots, and thumbnails. This package handles scaling and uniformity internally, reducing the need for manual image dimension calculations.
Choose react-photo-gallery when you need to display a collection of images simultaneously in a grid or masonry layout. It is ideal for portfolios, photo albums, or dashboards where context and overview matter more than sequence. Be aware that this package requires explicit width and height data for each image to calculate layout ratios correctly, and maintenance activity is slower compared to other options.
A responsive, customizable image gallery component for React
βΆοΈ VIEW LIVE DEMO

| Feature | Description |
|---|---|
| π± Mobile Swipe | Native touch gestures for smooth mobile navigation |
| πΌοΈ Thumbnails | Customizable thumbnail navigation with multiple positions |
| πΊ Fullscreen | Browser fullscreen or CSS-based fullscreen modes |
| π¨ Theming | CSS custom properties for easy styling |
| β¨οΈ Keyboard Nav | Arrow keys, escape, and custom key bindings |
| π RTL Support | Right-to-left language support |
| βοΈ Vertical Mode | Slide vertically instead of horizontally |
| π¬ Custom Slides | Render videos, iframes, or any custom content |
npm install react-image-gallery
import { useRef } from "react";
import ImageGallery from "react-image-gallery";
import "react-image-gallery/styles/image-gallery.css";
import type { GalleryItem, ImageGalleryRef } from "react-image-gallery";
const images: GalleryItem[] = [
{
original: "https://picsum.photos/id/1018/1000/600/",
thumbnail: "https://picsum.photos/id/1018/250/150/",
},
{
original: "https://picsum.photos/id/1015/1000/600/",
thumbnail: "https://picsum.photos/id/1015/250/150/",
},
{
original: "https://picsum.photos/id/1019/1000/600/",
thumbnail: "https://picsum.photos/id/1019/250/150/",
},
];
function MyGallery() {
const galleryRef = useRef<ImageGalleryRef>(null);
return (
<ImageGallery
ref={galleryRef}
items={images}
onSlide={(index) => console.log("Slid to", index)}
/>
);
}
For more examples, see example/App.jsx
items: (required) Array of objects. Available properties:
original - image source URLthumbnail - thumbnail source URLfullscreen - fullscreen image URL (defaults to original)originalHeight - image height (html5 attribute)originalWidth - image width (html5 attribute)loading - "lazy" or "eager" (HTML5 attribute)thumbnailHeight - image height (html5 attribute)thumbnailWidth - image width (html5 attribute)thumbnailLoading - "lazy" or "eager" (HTML5 attribute)originalClass - custom image classthumbnailClass - custom thumbnail classrenderItem - Function for custom rendering a specific slide (see renderItem below)renderThumbInner - Function for custom thumbnail renderer (see renderThumbInner below)originalAlt - image altthumbnailAlt - thumbnail image altoriginalTitle - image titlethumbnailTitle - thumbnail image titlethumbnailLabel - label for thumbnaildescription - description for imagesrcSet - image srcset (html5 attribute)sizes - image sizes (html5 attribute)bulletClass - extra class for the bullet of the iteminfinite: Boolean, default true - loop infinitelylazyLoad: Boolean, default falseshowNav: Boolean, default trueshowThumbnails: Boolean, default truethumbnailPosition: String, default bottom - options: top, right, bottom, leftshowFullscreenButton: Boolean, default trueuseBrowserFullscreen: Boolean, default true - if false, uses CSS-based fullscreenuseTranslate3D: Boolean, default true - if false, uses translate instead of translate3dshowPlayButton: Boolean, default trueisRTL: Boolean, default false - right-to-left modeshowBullets: Boolean, default falsemaxBullets: Number, default undefined - max bullets shown (minimum 3, active bullet stays centered)showIndex: Boolean, default falseautoPlay: Boolean, default falsedisableThumbnailScroll: Boolean, default false - disable thumbnail auto-scrolldisableKeyDown: Boolean, default false - disable keyboard navigationdisableSwipe: Boolean, default falsedisableThumbnailSwipe: Boolean, default falseonErrorImageURL: String, default undefined - fallback image URL for failed loadsindexSeparator: String, default ' / ', ignored if showIndex is falseslideDuration: Number, default 550 - slide transition duration (ms)swipingTransitionDuration: Number, default 0 - transition duration while swiping (ms)slideInterval: Number, default 3000slideOnThumbnailOver: Boolean, default falseslideVertically: Boolean, default false - slide vertically instead of horizontallyflickThreshold: Number, default 0.4 - swipe velocity threshold (lower = more sensitive)swipeThreshold: Number, default 30 - percentage of slide width needed to trigger navigationstopPropagation: Boolean, default false - call stopPropagation on swipe eventsstartIndex: Number, default 0onImageError: Function, callback(event) - overrides onErrorImageURLonThumbnailError: Function, callback(event) - overrides onErrorImageURLonThumbnailClick: Function, callback(event, index)onBulletClick: Function, callback(event, index)onImageLoad: Function, callback(event)onSlide: Function, callback(currentIndex)onBeforeSlide: Function, callback(nextIndex)onScreenChange: Function, callback(isFullscreen)onPause: Function, callback(currentIndex)onPlay: Function, callback(currentIndex)onClick: Function, callback(event)onTouchMove: Function, callback(event) on gallery slideonTouchEnd: Function, callback(event) on gallery slideonTouchStart: Function, callback(event) on gallery slideonMouseOver: Function, callback(event) on gallery slideonMouseLeave: Function, callback(event) on gallery slideadditionalClass: String, additional class for the root noderenderCustomControls: Function, render custom controls on the current sliderenderItem: Function, custom slide renderingrenderThumbInner: Function, custom thumbnail renderingrenderLeftNav: Function, custom left nav componentrenderRightNav: Function, custom right nav componentrenderTopNav: Function, custom top nav component (vertical mode)renderBottomNav: Function, custom bottom nav component (vertical mode)renderPlayPauseButton: Function, custom play/pause buttonrenderFullscreenButton: Function, custom fullscreen buttonuseWindowKeyDown: Boolean, default true - use window or element for key eventsThe following functions can be accessed using refs
play(): starts the slideshowpause(): pauses the slideshowtogglePlay(): toggles between play and pausefullScreen(): enters fullscreen modeexitFullScreen(): exits fullscreen modetoggleFullScreen(): toggles fullscreen modeslideToIndex(index): slides to a specific indexgetCurrentIndex(): returns the current indexPull requests should be focused on a single issue. If you're unsure whether a change is useful or involves a major modification, please open an issue first.
Requires Node.js >= 18.18
git clone https://github.com/xiaolin/react-image-gallery.git
cd react-image-gallery
npm install
npm start
Then open localhost:8001 in a browser.
MIT Β© Xiao Lin