An image and video lightbox gallery for the modern web. Available natively for JavaScript, React, Vue and Angular.
Real components for React, Vue and Angular, and plain JavaScript, each written for its framework, with the same features in every one of them.
Plain JavaScript, no dependencies. Point it at your markup or an array of items, from npm or a CDN.
npm install lightgalleryimport lightGallery from 'lightgallery';
import lgThumbnail from 'lightgallery/plugins/thumbnail';
import lgZoom from 'lightgallery/plugins/zoom';
import 'lightgallery/css/lightgallery-bundle.css';
lightGallery(document.getElementById('gallery'), {
plugins: [lgZoom, lgThumbnail],
});A real React component: props, children, refs and callbacks, all typed. Your state stays in React.
npm install @lightgallery/react lightgalleryimport { LightGallery, LightGalleryItem } from '@lightgallery/react';
import Thumbnail from '@lightgallery/react/plugins/thumbnail';
import Zoom from '@lightgallery/react/plugins/zoom';
<LightGallery plugins={[Zoom, Thumbnail]}>
{items.map((item) => (
<LightGalleryItem key={item.src} item={item}>
<img src={item.thumb} alt={item.alt} />
</LightGalleryItem>
))}
</LightGallery>;v-model for the open state, slots for captions and controls, Teleport for the overlay.
npm install @lightgallery/vue lightgallery<script setup>
import { LightGallery, LgItem } from '@lightgallery/vue';
import Thumbnail from '@lightgallery/vue/plugins/thumbnail';
import Zoom from '@lightgallery/vue/plugins/zoom';
</script>
<template>
<LightGallery :plugins="[Zoom, Thumbnail]">
<LgItem v-for="item of items" :key="item.src" :item="item">
<img :src="item.thumb" :alt="item.alt" />
</LgItem>
</LightGallery>
</template>Standalone components, signals, zoneless change detection and a CDK overlay, nothing bolted on.
npm install @lightgallery/angular @angular/cdk lightgallery<lg-gallery [features]="[withZoom(), withThumbnail()]">
@for (item of items; track item.src) {
<a [lgGalleryItem]="item">
<img [src]="item.thumb" [alt]="item.alt" />
</a>
}
</lg-gallery>Building for something else? The gallery’s core ships standalone, without a renderer, @lightgallery/headless.
Each of these has a page with a live demo and the settings behind it.
New in v3Animated or static strips, fetched automatically for YouTube and Vimeo, draggable on every device.
Pinch and double-tap to zoom. Slides open from the thumbnail's position and close back to it.
YouTube, Vimeo, Wistia and HTML5 video, with autoplay-on-slide and posters. Facades load the player only when someone presses play.
Row-justified trigger grids from one plugin, no layout library in front of the lightbox.
Thousand-slide galleries keep a few dozen nodes in the DOM; slides and thumbnails mount as they come into view.
Drag the thumbnail strip and the gallery follows instantly, all the way through the release glide.
Every control icon is an inline SVG you can replace by name, bring your own set without touching CSS.
Every string is a setting, and the gallery mirrors for right-to-left pages, navigation, swipe direction and chrome.
Keyboard navigation, focus management and screen-reader announcements out of the box.
Size ladders and srcset for the lightbox image, so phones never download the desktop original.
The device's native share sheet where it exists, social links where it doesn't.
A URL for every slide, with browser back and forward, on hash or history drivers.
Open a gallery from an array of items, no trigger markup required.
Add, edit and remove slides while the gallery is open.
Twenty-plus slide transitions, hardware accelerated, plus your own easing.
HTML captions per slide, from markup or data, with animated and relative-position variants.
A per-slide comment panel with Facebook and Disqus adapters, or your own widget.
Rotate and flip any image, with hooks to persist the result.
Slideshow with a progress bar that pauses on interaction, and native fullscreen from the toolbar.
Minimal dot navigation instead of a strip, with thumbnails on hover.
Photos, videos and iframes in one gallery, maps and PDFs included, each slide sized for what it holds.
Every release is a spring seeded with the user’s velocity. Flings land where they should, edges push back, nothing snaps.
The last 100 ms of your gesture seed the release spring. Motion continues from the speed you let go at, it never restarts from zero.
A fling projects its landing point with the same deceleration curve native scroll views use, then settles there.
Slides, the thumbnail strip and zoom panning resist at the boundary with friction instead of stopping dead, and return with a single soft bounce.
Pinch anchors to the point between your fingertips, pan included, so what you zoom into is what you look at.
Catch a slide mid-spring and it hands you its live position and velocity; the next release starts a new spring from exactly there.
JavaScript, React, Vue and Angular share the same feel, not a port of it, so nothing is tuned differently in yours.
Settings for behavior, SCSS variables for looks, your own icons, and a plugin API for everything else. The core stays untouched.
Core and per-plugin options, with a separate set for mobile, every one documented in the generated reference
Colors, spacing and transitions are variables, retheme the gallery from one file
Thumbnails, zoom, video and the rest are plugins built on the same API you get, add your own
Every control icon is an inline SVG you can replace by name, bring your own set, no CSS required
$lg-theme-color: #fff; $lg-icon-color: #555; $lg-theme-highlight: #333;plugins: [lgZoom, buyNow] icons: boldIcons download: false .lg-icon { border-radius: 50% }Click on any thumbnail to open lightGallery
The same gallery, embedded in the page. One click on the maximize icon takes it fullscreen, same settings, same plugins.
Every feature outside the core is a plugin with its own entry point. Import the two you use and the rest never reach your bundle. Sizes are from this site’s build, minified and gzipped.
import lightGallery from 'lightgallery';
import lgThumbnail from 'lightgallery/plugins/thumbnail';
import lgZoom from 'lightgallery/plugins/zoom';
// Two plugins, two imports, nothing else ships.
lightGallery(el, { plugins: [lgZoom, lgThumbnail] });Most gallery views happen on a phone, and some happen without a mouse or a screen. The defaults assume both.
srcset mean a phone never downloads the desktop original.Yes. lightGallery is free and open source under the GPLv3, for personal and commercial projects alike, as long as your project is distributed under GPLv3-compatible terms. If you keep your source proprietary, a commercial license covers it: same code, no feature gates, one-time payment.
No. lightGallery has no dependencies. The only jQuery on this site is for the two demos that integrate third-party jQuery carousels.
Plain JavaScript and TypeScript, plus native packages for React, Vue and Angular, the same features in all of them. For anything else, the gallery’s core is available on its own as @lightgallery/headless.
Current evergreen browsers and iOS Safari. There are no polyfills and no legacy builds.
Version 3 is a complete rewrite with smoother touch gestures, faster loading, accessibility and new features like justified layouts, while the vanilla API stays unchanged. The framework wrappers are replaced by native packages and the icon font is gone. The release post has what’s new, and the migration guide lists every step.
Yes, every package ships its own types; settings, events and plugin options are fully typed.
In production at thousands of teams since 2014, from solo developers to the world’s biggest brands. Live in minutes.
or browse the demos first.