react-alice-carousel, react-image-gallery, react-responsive-carousel, and react-slick are all React libraries designed to handle sliding content, image galleries, and carousel interactions. While they share the core goal of displaying content in a navigable sequence, they differ significantly in architecture, dependency management, and feature focus. react-slick is a React wrapper around the jQuery-based Slick Carousel, offering a mature but heavier solution. react-responsive-carousel is a lightweight, dependency-free option optimized for server-side rendering. react-image-gallery specializes in thumbnail-driven galleries with lightbox capabilities, and react-alice-carousel focuses on touch-friendly, infinite looping experiences with minimal configuration.
Choosing the right carousel library in React can significantly impact your application's performance, accessibility, and maintenance burden. react-alice-carousel, react-image-gallery, react-responsive-carousel, and react-slick all solve the sliding content problem, but they approach it from different architectural angles. Let's compare how they handle setup, rendering, responsiveness, and server-side compatibility.
How you import and style these libraries varies wildly, affecting your build configuration and global CSS scope.
react-alice-carousel requires importing both the JS component and its CSS file explicitly.
// react-alice-carousel: Explicit CSS import
import AliceCarousel from 'react-alice-carousel';
import 'react-alice-carousel/lib/alice-carousel.css';
const Carousel = () => <AliceCarousel items={items} />;
react-image-gallery also requires manual CSS import, often needing SCSS processing depending on your setup.
// react-image-gallery: Explicit CSS import
import ImageGallery from 'react-image-gallery';
import 'react-image-gallery/styles/css/image-gallery.css';
const Gallery = () => <ImageGallery items={images} />;
react-responsive-carousel similarly requires you to import the CSS manually.
// react-responsive-carousel: Explicit CSS import
import { Carousel } from 'react-responsive-carousel';
import 'react-responsive-carousel/lib/styles/carousel.min.css';
const CarouselComp = () => <Carousel>{items}</Carousel>;
react-slick relies on external CSS files from the original Slick Carousel library.
// react-slick: Multiple CSS imports
import Slider from 'react-slick';
import 'slick-carousel/slick/slick.css';
import 'slick-carousel/slick/slick-theme.css';
const SliderComp = () => <Slider>{items}</Slider>;
The API for passing content into the carousel dictates how flexible your slides can be.
react-alice-carousel accepts items via a prop, usually an array of React nodes.
// react-alice-carousel: Items prop
const items = [
<div className="item">1</div>,
<div className="item">2</div>
];
<AliceCarousel items={items} />;
react-image-gallery expects a specific array of objects with original, thumbnail, and description keys.
// react-image-gallery: Specific object structure
const images = [
{ original: 'img1.jpg', thumbnail: 'thumb1.jpg' },
{ original: 'img2.jpg', thumbnail: 'thumb2.jpg' }
];
<ImageGallery items={images} />;
react-responsive-carousel uses standard React children, making it very flexible.
// react-responsive-carousel: Children prop
<Carousel>
<div><img src="img1.jpg" /></div>
<div><img src="img2.jpg" /></div>
</Carousel>
react-slick also uses children for slides.
// react-slick: Children prop
<Slider>
<div><img src="img1.jpg" /></div>
<div><img src="img2.jpg" /></div>
</Slider>
Handling different screen sizes is critical for carousels. The configuration ergonomics differ here.
react-alice-carousel uses a responsive prop with an object defining breakpoints.
// react-alice-carousel: Responsive object
const responsive = {
0: { items: 1 },
720: { items: 3 },
1024: { items: 5 }
};
<AliceCarousel responsive={responsive} items={items} />;
react-image-gallery handles responsiveness mostly via CSS and internal logic.
// react-image-gallery: Limited slide config
// Primarily relies on CSS media queries for layout
<ImageGallery
items={images}
showThumbnails={true}
/>;
react-responsive-carousel does not have built-in breakpoint props for item counts.
// react-responsive-carousel: Manual CSS control
<Carousel showArrows={true}>
{/* CSS media queries handle visibility/size */}
<div className="slide">Content</div>
</Carousel>
react-slick uses a responsive array of objects, similar to Alice but more verbose.
// react-slick: Responsive array
const settings = {
responsive: [
{ breakpoint: 768, settings: { slidesToShow: 2 } },
{ breakpoint: 1024, settings: { slidesToShow: 4 } }
]
};
<Slider {...settings}>{children}</Slider>;
Server-side rendering compatibility is a major differentiator, as many carousels rely on window measurements.
react-alice-carousel generally supports SSR but may require disabling SSR for the component to avoid hydration mismatches.
window for touch calculations which can crash Node environments.useEffect or dynamic import.// react-alice-carousel: SSR workaround
const [isClient, setIsClient] = useState(false);
useEffect(() => setIsClient(true), []);
if (!isClient) return null;
return <AliceCarousel items={items} />;
react-image-gallery can be tricky with SSR due to image dimension calculations.
// react-image-gallery: SSR consideration
// Often requires dynamic import in Next.js
const ImageGallery = dynamic(() => import('react-image-gallery'), { ssr: false });
react-responsive-carousel is known for excellent SSR support out of the box.
window dependencies during initial render.// react-responsive-carousel: SSR friendly
// Works directly in server components with minimal setup
<Carousel>
<div>Slide 1</div>
<div>Slide 2</div>
</Carousel>
react-slick is notorious for SSR issues (window is not defined).
ssr: true in settings AND a dynamic import.// react-slick: SSR mandatory config
const settings = { ssr: true, infinite: false };
// Usually wrapped in no-ssr component or dynamic import
<Slider {...settings}>{children}</Slider>;
You need to show 5 products per row on desktop, 1 on mobile, with infinite looping.
react-alice-carousel// react-alice-carousel
<AliceCarousel
items={products}
responsive={{ 0: { items: 1 }, 1000: { items: 5 } }}
infinite={true}
/>
You need a grid of images that open in a lightbox with thumbnail navigation.
react-image-gallery// react-image-gallery
<ImageGallery
items={photos}
showThumbnails={true}
showLightbox={true}
/>
A simple fade or slide animation for a hero banner on a content site.
react-responsive-carousel// react-responsive-carousel
<Carousel showArrows={false} autoPlay infiniteLoop>
<div><img src="hero1.jpg" /></div>
<div><img src="hero2.jpg" /></div>
</Carousel>
You need complex easing, variable widths, and specific navigation dots.
react-slick// react-slick
<Slider dots={true} infinite={true} speed={500} slidesToShow={3}>
<div>Widget 1</div>
<div>Widget 2</div>
</Slider>
| Feature | react-alice-carousel | react-image-gallery | react-responsive-carousel | react-slick |
|---|---|---|---|---|
| Primary Use | General Purpose Carousel | Photo Gallery + Lightbox | Simple SSR Carousel | Complex Legacy Slider |
| Dependencies | Low | Low | None | High (jQuery port logic) |
| SSR Support | ⚠️ Requires Workaround | ⚠️ Requires Workaround | ✅ Excellent | ⚠️ Requires Config |
| API Style | Props (items) | Props (items array) | Children (jsx) | Children (jsx) |
| Responsiveness | ✅ Configurable Breakpoints | 📐 CSS Based | 📐 CSS Based | ✅ Configurable Breakpoints |
| Touch Support | ✅ Native | ✅ Native | ✅ Native | ✅ Native |
react-slick is the veteran of the group 🐢 — powerful and feature-rich, but carries the weight of older architecture. It's a solid choice for complex, internal tools where bundle size matters less than configuration depth.
react-image-gallery is a specialist 📸 — don't use it for generic content sliders. If you need thumbnails and lightboxes, it's the undisputed leader. For anything else, look elsewhere.
react-responsive-carousel is the minimalist 🍃 — perfect for modern React apps (Next.js, Remix) where SSR and simplicity are key. It gets out of your way and lets you build standard carousels quickly.
react-alice-carousel is the balanced contender ⚖️ — offers a great mix of responsiveness and features without the heaviness of Slick. It's often the best default choice for new e-commerce or marketing projects.
Final Thought: All four libraries can get the job done, but your choice should depend on SSR requirements and content structure. If you need a lightbox, pick react-image-gallery. If you need SSR without headaches, pick react-responsive-carousel. If you need complex responsive breakpoints, pick react-alice-carousel or react-slick.
Choose react-image-gallery if your primary use case is a photo gallery with thumbnails and a lightbox modal. It is the best fit for portfolios or e-commerce product images where users expect to click a thumbnail to view a larger version in an overlay.
Choose react-alice-carousel if you need a lightweight, touch-optimized carousel with support for infinite looping and variable item widths. It is ideal for product sliders or testimonial sections where responsiveness and swipe gestures are critical without the overhead of older jQuery-based ports.
Choose react-responsive-carousel if you prioritize server-side rendering (SSR) compatibility and zero external dependencies. It is suitable for content-heavy sites like blogs or marketing pages where performance and SEO are top priorities.
Choose react-slick if you need a battle-tested solution with a vast array of configuration options and don't mind managing CSS dependencies manually. It works well for legacy projects or complex sliders requiring specific easing and animation controls that newer libraries might not support yet.
A responsive, customizable image gallery component for React

| 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