react-image-gallery vs react-photo-gallery
Image Display Architectures: Sliders vs. Grids
react-image-galleryreact-photo-gallery

Image Display Architectures: Sliders vs. Grids

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.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
react-image-gallery03,940123 kB147 months agoMIT
react-photo-gallery02,014-807 years agoMIT

react-image-gallery vs react-photo-gallery: Layout Engines and Interaction Models

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.

πŸ“ Layout Engine: Sequential Slides vs. Responsive Grids

react-image-gallery renders images in a single viewport, showing one slide at a time.

  • It manages the container size and scales images to fit.
  • Best for scenarios where focus should remain on a single image.
// 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.

  • It calculates row heights based on aspect ratios to prevent cropping.
  • Best for scenarios where users scan many images at once.
// 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} />

πŸ“₯ Data Requirements: Uniform vs. Aspect Ratio

react-image-gallery works best with uniform or flexible image sizes.

  • You provide original and thumbnail URLs.
  • The component handles resizing and cropping within the slide container.
  • No need to know exact dimensions beforehand.
// 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.

  • It uses these numbers to calculate the masonry or grid layout.
  • Missing dimensions can break the layout or cause layout shifts.
  • You often need to fetch metadata before rendering.
// 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} />

πŸ–±οΈ Interaction Patterns: Navigation vs. Selection

react-image-gallery provides built-in navigation controls.

  • Includes next/prev arrows, swipe gestures, and thumbnail strips.
  • Supports fullscreen mode and keyboard navigation out of the box.
  • Ideal for guided tours or product inspections.
// 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.

  • Does not include built-in lightboxes or sliders.
  • You must build or integrate a separate viewer for full-size viewing.
  • Ideal for selecting items or triggering actions from a grid.
// 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

πŸ› οΈ Maintenance & Ecosystem Stability

react-image-gallery has a consistent release history.

  • Regularly updated to support newer React versions.
  • Wide adoption in e-commerce and marketing sites.
  • Lower risk of breaking changes in production.
// 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.

  • Community reports indicate longer gaps between releases.
  • May require forks or patches for modern React compatibility.
  • Consider alternatives like 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

🀝 Similarities: Shared Ground Between Packages

While their layouts differ, both packages share common goals and patterns.

1. βš›οΈ React Component Structure

  • Both are functional components accepting props.
  • Support standard React events like onClick and onLoad.
// Both: Standard React props
<ImageGallery items={items} className="custom-gallery" />
<Gallery photos={photos} className="custom-grid" />

2. πŸ–ΌοΈ Image Loading Handling

  • Both rely on standard <img> tags under the hood.
  • Support lazy loading strategies (native or via props).
// 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} />

3. 🎨 Custom Styling

  • Both allow CSS customization via class names.
  • Do not enforce strict inline styles, allowing theme integration.
// Both: Custom classes
<ImageGallery className="my-slider" />
<Gallery className="my-grid" />

πŸ“Š Summary: Key Differences

Featurereact-image-galleryreact-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

πŸ’‘ The Big Picture

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.

How to Choose: react-image-gallery vs react-photo-gallery

  • react-image-gallery:

    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.

  • react-photo-gallery:

    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.

README for react-image-gallery

React Image Gallery

A responsive, customizable image gallery component for React


npm version Download Count Bundle size CI TypeScript License: MIT


▢️ VIEW LIVE DEMO


React Image Gallery Demo


✨ Features

FeatureDescription
πŸ“± Mobile SwipeNative touch gestures for smooth mobile navigation
πŸ–ΌοΈ ThumbnailsCustomizable thumbnail navigation with multiple positions
πŸ“Ί FullscreenBrowser fullscreen or CSS-based fullscreen modes
🎨 ThemingCSS custom properties for easy styling
⌨️ Keyboard NavArrow keys, escape, and custom key bindings
πŸ”„ RTL SupportRight-to-left language support
↕️ Vertical ModeSlide vertically instead of horizontally
🎬 Custom SlidesRender videos, iframes, or any custom content

πŸš€ Getting Started

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


βš™οΈ Props

  • items: (required) Array of objects. Available properties:
    • original - image source URL
    • thumbnail - thumbnail source URL
    • fullscreen - 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 class
    • thumbnailClass - custom thumbnail class
    • renderItem - Function for custom rendering a specific slide (see renderItem below)
    • renderThumbInner - Function for custom thumbnail renderer (see renderThumbInner below)
    • originalAlt - image alt
    • thumbnailAlt - thumbnail image alt
    • originalTitle - image title
    • thumbnailTitle - thumbnail image title
    • thumbnailLabel - label for thumbnail
    • description - description for image
    • srcSet - image srcset (html5 attribute)
    • sizes - image sizes (html5 attribute)
    • bulletClass - extra class for the bullet of the item
  • infinite: Boolean, default true - loop infinitely
  • lazyLoad: Boolean, default false
  • showNav: Boolean, default true
  • showThumbnails: Boolean, default true
  • thumbnailPosition: String, default bottom - options: top, right, bottom, left
  • showFullscreenButton: Boolean, default true
  • useBrowserFullscreen: Boolean, default true - if false, uses CSS-based fullscreen
  • useTranslate3D: Boolean, default true - if false, uses translate instead of translate3d
  • showPlayButton: Boolean, default true
  • isRTL: Boolean, default false - right-to-left mode
  • showBullets: Boolean, default false
  • maxBullets: Number, default undefined - max bullets shown (minimum 3, active bullet stays centered)
  • showIndex: Boolean, default false
  • autoPlay: Boolean, default false
  • disableThumbnailScroll: Boolean, default false - disable thumbnail auto-scroll
  • disableKeyDown: Boolean, default false - disable keyboard navigation
  • disableSwipe: Boolean, default false
  • disableThumbnailSwipe: Boolean, default false
  • onErrorImageURL: String, default undefined - fallback image URL for failed loads
  • indexSeparator: String, default ' / ', ignored if showIndex is false
  • slideDuration: Number, default 550 - slide transition duration (ms)
  • swipingTransitionDuration: Number, default 0 - transition duration while swiping (ms)
  • slideInterval: Number, default 3000
  • slideOnThumbnailOver: Boolean, default false
  • slideVertically: Boolean, default false - slide vertically instead of horizontally
  • flickThreshold: Number, default 0.4 - swipe velocity threshold (lower = more sensitive)
  • swipeThreshold: Number, default 30 - percentage of slide width needed to trigger navigation
  • stopPropagation: Boolean, default false - call stopPropagation on swipe events
  • startIndex: Number, default 0
  • onImageError: Function, callback(event) - overrides onErrorImageURL
  • onThumbnailError: Function, callback(event) - overrides onErrorImageURL
  • onThumbnailClick: 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 slide
  • onTouchEnd: Function, callback(event) on gallery slide
  • onTouchStart: Function, callback(event) on gallery slide
  • onMouseOver: Function, callback(event) on gallery slide
  • onMouseLeave: Function, callback(event) on gallery slide
  • additionalClass: String, additional class for the root node
  • renderCustomControls: Function, render custom controls on the current slide
  • renderItem: Function, custom slide rendering
  • renderThumbInner: Function, custom thumbnail rendering
  • renderLeftNav: Function, custom left nav component
  • renderRightNav: Function, custom right nav component
  • renderTopNav: Function, custom top nav component (vertical mode)
  • renderBottomNav: Function, custom bottom nav component (vertical mode)
  • renderPlayPauseButton: Function, custom play/pause button
  • renderFullscreenButton: Function, custom fullscreen button
  • useWindowKeyDown: Boolean, default true - use window or element for key events

πŸ”§ Functions

The following functions can be accessed using refs

  • play(): starts the slideshow
  • pause(): pauses the slideshow
  • togglePlay(): toggles between play and pause
  • fullScreen(): enters fullscreen mode
  • exitFullScreen(): exits fullscreen mode
  • toggleFullScreen(): toggles fullscreen mode
  • slideToIndex(index): slides to a specific index
  • getCurrentIndex(): returns the current index

🀝 Contributing

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

  • Follow the eslint config
  • Comment your code

πŸ› οΈ Build the example locally

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.


πŸ“„ License

MIT Β© Xiao Lin