
Company News
Andrew Becherer Joins Socket as Chief Information Security Officer
Socket’s first CISO brings deep experience securing high-growth SaaS companies as open source supply chain threats accelerate.
@reelkit/react-lightbox
Advanced tools
Full-screen image and video gallery lightbox for React with touch gestures, transitions, and render props
Image gallery lightbox for React — opens full-screen with swipe navigation, keyboard controls, and transition effects. Everything is replaceable via render props if the defaults don't fit. ~3.2 kB gzip.
npm install @reelkit/react-lightbox @reelkit/react lucide-react
import { useState } from 'react';
import { LightboxOverlay, type LightboxItem } from '@reelkit/react-lightbox';
import '@reelkit/react-lightbox/styles.css';
const images: LightboxItem[] = [
{
src: 'https://example.com/image1.jpg',
title: 'Sunset',
description: 'Beautiful sunset over the ocean',
},
{
src: 'https://example.com/image2.jpg',
title: 'Mountains',
},
];
function App() {
const [index, setIndex] = useState<number | null>(null);
return (
<>
{images.map((img, i) => (
<img key={i} src={img.src} onClick={() => setIndex(i)} />
))}
<LightboxOverlay
isOpen={index !== null}
images={images}
initialIndex={index ?? 0}
onClose={() => setIndex(null)}
/>
</>
);
}
slideTransition, flipTransition, lightboxFadeTransition, lightboxZoomTransition (import only what you use)useVideoSlideRendererrenderControls, renderNavigation, renderInfo, renderSlide to override any part of the UICloseButton, Counter, FullscreenButton, SoundButton for composing custom controls| Prop | Type | Default | Description |
|---|---|---|---|
isOpen | boolean | required | Controls lightbox visibility |
images | LightboxItem[] | required | Array of images to display |
initialIndex | number | 0 | Starting image index |
transitionFn | TransitionTransformFn | slideTransition | Slide transition fn (built-in or custom) |
apiRef | MutableRefObject<ReelApi> | - | Ref to access Reel API |
renderControls | (props) => ReactNode | - | Custom controls |
renderNavigation | (props) => ReactNode | - | Custom navigation arrows |
renderInfo | (props) => ReactNode | - | Custom info overlay |
renderSlide | (item, index, size, isActive) => ReactNode | null | - | Custom slide rendering |
| Prop | Type | Description |
|---|---|---|
onClose | () => void | Called when lightbox closes |
onSlideChange | (index: number) => void | Called after slide change |
| Prop | Type | Default | Description |
|---|---|---|---|
loop | boolean | false | Enable infinite loop |
enableNavKeys | boolean | true | Enable keyboard navigation |
enableWheel | boolean | true | Enable mouse wheel |
wheelDebounceMs | number | 200 | Wheel debounce (ms) |
transitionDuration | number | 300 | Animation duration (ms) |
swipeDistanceFactor | number | 0.12 | Swipe threshold (0-1) |
interface LightboxItem {
src: string;
type?: 'image' | 'video'; // defaults to 'image'
poster?: string; // thumbnail for video items
title?: string;
description?: string;
width?: number;
height?: number;
}
Video support is tree-shakeable — image-only usage pays zero extra bundle cost. Import useVideoSlideRenderer and wire it into LightboxOverlay to enable video slides.
import {
LightboxOverlay,
Counter,
CloseButton,
SoundButton,
useVideoSlideRenderer,
type LightboxItem,
} from '@reelkit/react-lightbox';
import '@reelkit/react-lightbox/styles.css';
const items: LightboxItem[] = [
{ src: '/photo.jpg', title: 'Photo' },
{
src: '/clip.mp4',
type: 'video',
poster: '/clip-thumb.jpg',
title: 'Video Clip',
},
];
function Gallery() {
const [index, setIndex] = useState<number | null>(null);
const isOpen = index !== null;
const { renderSlide, isMuted, onToggleMute, hasVideo } =
useVideoSlideRenderer(items, isOpen);
return (
<>
{/* thumbnails… */}
<LightboxOverlay
isOpen={isOpen}
images={items}
initialIndex={index ?? 0}
onClose={() => setIndex(null)}
renderSlide={renderSlide}
renderControls={({ onClose, currentIndex, count }) => (
<>
<div className="rk-lightbox-controls-left">
<Counter currentIndex={currentIndex} count={count} />
{hasVideo && (
<SoundButton isMuted={isMuted} onToggle={onToggleMute} />
)}
</div>
<CloseButton onClick={onClose} />
</>
)}
/>
</>
);
}
function useVideoSlideRenderer(
items: LightboxItem[],
isOpen?: boolean,
): {
renderSlide: (item, index, size, isActive) => ReactNode | null;
isMuted: boolean; // current mute state (default: true)
onToggleMute: () => void;
hasVideo: boolean; // true if items contain at least one video
};
Pass isOpen to reset muted state when the lightbox closes (enables autoplay on reopen).
| Prop | Type | Description |
|---|---|---|
isMuted | boolean | Current mute state |
onToggle | () => void | Toggle callback |
className | string | CSS class (default: rk-lightbox-btn) |
style | CSSProperties | Inline styles |
| Key | Action |
|---|---|
ArrowLeft | Previous image |
ArrowRight | Next image |
Escape | Close lightbox (or exit fullscreen) |
All UI elements use CSS classes prefixed with rk-lightbox- that can be overridden:
| Class | Description |
|---|---|
.rk-lightbox-overlay | Root container |
.rk-lightbox-close | Close button |
.rk-lightbox-nav | Navigation arrows |
.rk-lightbox-nav-prev | Previous arrow |
.rk-lightbox-nav-next | Next arrow |
.rk-lightbox-counter | Image counter |
.rk-lightbox-btn | Control buttons |
.rk-lightbox-info | Title/description container |
.rk-lightbox-title | Image title |
.rk-lightbox-description | Image description |
.rk-lightbox-slide | Slide container |
.rk-lightbox-img | Image element |
.rk-lightbox-video-container | Video slide wrapper |
.rk-lightbox-video-element | Video element |
.rk-lightbox-video-poster | Video poster image |
.rk-lightbox-spinner | Default loading spinner |
.rk-lightbox-img-error | Error state container |
.rk-lightbox-swipe-hint | Mobile swipe hint chip |
Every visual value is exposed as a --rk-lightbox-* custom property with a sensible default. Override at :root (or any ancestor of .rk-lightbox-overlay) to retheme without touching component source — see the Theming docs for the full token table.
Docs, demos, and customization examples at reelkit.dev/docs/lightbox.
If ReelKit saved you some time, a star on GitHub would mean a lot — it's a small thing, but it really helps the project get noticed.
FAQs
Full-screen image and video gallery lightbox for React with touch gestures, transitions, and render props
We found that @reelkit/react-lightbox demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Socket’s first CISO brings deep experience securing high-growth SaaS companies as open source supply chain threats accelerate.

Company News
Replit is integrating Socket Firewall into its AI-powered development experience to help protect builders from malicious open source packages.

Security News
npm confirmed a tooling bug incorrectly marked several one-character packages as security holders and said it was working on a rollback.