lightgallery.js, magnific-popup, and photoswipe are all JavaScript libraries designed to create image lightboxes (modal galleries) on web pages, but they serve different architectural needs. lightgallery.js is a modular, plugin-based gallery that excels at handling complex media types (videos, iframes) and offers extensive customization through a rich ecosystem of addons. magnific-popup is a lightweight, flexible dialog script that focuses on inline content and AJAX loading, often used for simple popups beyond just images. photoswipe is a framework-agnostic, touch-optimized library built specifically for high-performance image viewing on mobile devices, prioritizing gesture support and smooth transitions over feature bloat.
When building image galleries or modal viewers, frontend architects often face a trade-off between feature richness, mobile performance, and flexibility. lightgallery.js, magnific-popup, and photoswipe are three established solutions, but they solve different problems. Let's break down their technical architectures to help you make the right call.
lightgallery.js is built as a modular core with a plugin ecosystem.
// lightgallery: Modular initialization with plugins
import lightGallery from 'lightgallery/js';
import lgThumbnail from 'lightgallery/plugins/thumbnail';
import lgZoom from 'lightgallery/plugins/zoom';
const gallery = lightGallery(document.getElementById('gallery'), {
plugins: [lgThumbnail, lgZoom],
speed: 500
});
magnific-popup acts as a generic dialog manager rather than a strict gallery.
// magnific-popup: Generic dialog initialization
import 'magnific-popup';
$('.popup-with-form').magnificPopup({
type: 'inline',
preloader: false,
focus: '#name',
callbacks: {
beforeOpen: function() {
// Custom logic before opening
}
}
});
photoswipe is a low-level framework designed specifically for image viewing gestures.
// photoswipe: Core initialization with separate UI
import PhotoSwipe from 'photoswipe';
import PhotoSwipeUI_Default from 'photoswipe/dist/photoswipe-ui-default';
const gallery = new PhotoSwipe({
gallery: document.querySelector('.my-gallery'),
children: 'a',
pswpModule: () => import('photoswipe'),
showHideAnimationType: 'zoom'
});
gallery.init();
lightgallery.js provides touch support through its core and plugins.
lgZoom plugin.// lightgallery: Enabling touch zoom via plugin
const gallery = lightGallery(element, {
plugins: [lgZoom],
mobileSettings: {
controls: false,
showCloseIcon: false
}
});
magnific-popup has basic touch support but lacks advanced gestures.
// magnific-popup: Basic mobile configuration
$('.image-link').magnificPopup({
type: 'image',
tLoading: 'Loading image #%curr%...',
mainClass: 'mfp-img-mobile',
image: {
verticalFit: true
}
});
photoswipe is the gold standard for mobile touch interactions.
// photoswipe: Native-like gesture configuration
const gallery = new PhotoSwipe({
pinchToClose: true,
closeOnVerticalDrag: true,
allowPanToNext: true,
spacing: 0.12
});
lightgallery.js excels at handling mixed media types seamlessly.
// lightgallery: Supporting video and images together
import lgVideo from 'lightgallery/plugins/video';
lightGallery(element, {
plugins: [lgVideo],
exThumbImage: 'data-exthumbimage',
videojs: true // Enable Video.js integration
});
magnific-popup handles mixed content well but treats them as distinct types.
type (image, iframe, inline, ajax) for each element.// magnific-popup: Handling different content types
$('.popup-youtube').magnificPopup({
type: 'iframe',
iframe: {
markup: '<div class="mfp-iframe-scaler">...</div>',
patterns: {
youtube: {
index: 'youtube.com/',
id: 'v=',
src: 'https://www.youtube.com/embed/%id%?autoplay=1'
}
}
}
});
photoswipe is strictly for images.
// photoswipe: Strictly image data structure
const slides = [
{
src: 'https://example.com/image1.jpg',
w: 1024,
h: 768,
msrc: 'https://example.com/thumb1.jpg'
},
{
src: 'https://example.com/image2.jpg',
w: 1024,
h: 768
}
];
// No native support for video src types
lightgallery.js offers a robust event system and plugin API.
beforeSlide, afterSlide, or init to inject custom logic.// lightgallery: Event listening for custom logic
element.addEventListener('lgBeforeSlide', function(event) {
const index = event.detail.index;
console.log('Moving to slide', index);
});
magnific-popup provides callbacks but limited structural extensibility.
// magnific-popup: Callback usage
$('.popup').magnificPopup({
callbacks: {
open: function() {
// Called when opened
},
close: function() {
// Called when closed
}
}
});
photoswipe exposes a clean API but expects you to build the UI layer.
// photoswipe: Listening to internal events
gallery.on('change', () => {
console.log('Slide changed to', gallery.currSlide);
});
gallery.on('close', () => {
console.log('Gallery closed');
});
You need to show product images, 360-degree views, and promotional videos in a single carousel.
lightgallery.js// lightgallery: Mixed media gallery
lightGallery('#product-gallery', {
plugins: [lgThumbnail, lgVideo],
selector: '.item'
});
You need a popup that loads an inline contact form or an AJAX-loaded terms of service page.
magnific-popup// magnific-popup: Inline form modal
$('#open-form').magnificPopup({
items: {
src: '#hidden-form',
type: 'inline'
}
});
You need a full-screen, immersive image browsing experience with perfect pinch-to-zoom on iPads and phones.
photoswipe// photoswipe: High-fidelity image viewer
const pswp = new PhotoSwipe({
gallery: '#photo-portfolio',
children: 'a',
bgOpacity: 0.9,
padding: { top: 20, bottom: 40, left: 10, right: 10 }
});
pswp.init();
| Feature | lightgallery.js | magnific-popup | photoswipe |
|---|---|---|---|
| Primary Focus | Modular Media Gallery | Flexible Dialog System | Touch-Optimized Image Viewer |
| Touch Gestures | Good (Swipe + Plugin Zoom) | Basic (Swipe only) | Excellent (Pinch, Double-tap, Swipe) |
| Media Types | Images, Video, Iframes | Images, Inline, AJAX, Iframes | Images Only |
| Dependencies | None (Modular) | jQuery (Optional but common) | None |
| Customization | High (Plugin API) | Medium (Callbacks/Templates) | High (UI separated from Core) |
| Bundle Strategy | Tree-shakable Plugins | Monolithic Script | Core + UI Bundle |
Think about your content types and target devices:
lightgallery.js. Its modular plugin system is the most maintainable way to handle mixed media.magnific-popup. It is the most flexible "dialog" tool, even if it's not a strict gallery.photoswipe. Nothing else matches its gesture fidelity and performance for pure image browsing.Final Thought: While magnific-popup is versatile, it is showing its age in terms of mobile gesture support. For modern, image-centric applications, photoswipe offers the best user experience, while lightgallery.js provides the best balance of features for general-purpose content galleries.
Choose lightgallery.js if you need a full-featured gallery solution that supports diverse media types like YouTube videos, Vimeo, and HTML5 video alongside images. It is the best fit for projects requiring a modular architecture where you only load specific plugins (like thumbnails or zoom) to keep bundle sizes efficient while maintaining high customizability.
Choose magnific-popup if your primary requirement is a flexible dialog system that handles not just images, but also inline HTML content, AJAX responses, and iframes with minimal setup. It is ideal for legacy projects or simple implementations where you need a quick, dependency-free solution for various popup scenarios without the overhead of a dedicated gallery framework.
Choose photoswipe if your application targets mobile users heavily and requires native-like touch gestures (pinch-to-zoom, swipe) and high-performance animations. It is the superior choice for photography portfolios or image-heavy sites where the user experience of browsing images smoothly on touch devices is more critical than supporting complex mixed-media content.
Full featured JavaScript lightbox gallery. No dependencies.

lightgallery supports all major browsers including IE 9 and above.
You can install lightgallery.js using the npm package manager.
npm install lightgallery.js
You can also find lightgallery.js on Yarn and Bower.
yarn add lightgallery.js
bower install lightgallery.js --save
http://www.jsdelivr.com/projects/lightgallery.js
You can also directly download lightgallery from GitHub.
First of all add lightgallery.css in the <head> of the document.
<head>
<link rel="stylesheet" href="css/lightgallery.css">
</head>
Then include lightgallery.min.js into your document.
If you want to include any lightgallery plugin you can include it after lightgallery.min.js.
<body>
...
<script src="js/lightgallery.min.js"></script>
<!-- lightgallery plugins -->
<script src="js/lg-thumbnail.min.js"></script>
<script src="js/lg-fullscreen.min.js"></script>
</body>
Lightgallery also supports AMD, CommonJS and ES6 modules. When you use AMD make sure that lightgallery.js is loaded before lightgallery modules.
require(['./lightgallery.js'], function() {
require(["./lg-zoom.js", "./lg-thumbnail.js"], function(){
lightGallery(document.getElementById('lightgallery'));
});
});
lightgallery does not force you to use any kind of markup. You can use whatever markup you want. But i suggest you to use the following markup. Here you can find the detailed examples of different kinds of markup.
<div id="lightgallery">
<a href="https://github.com/sachinchoolur/lightgallery.js/blob/HEAD/img/img1.jpg">
<img src="https://raw.githubusercontent.com/sachinchoolur/lightgallery.js/HEAD/img/thumb1.jpg">
</a>
<a href="https://github.com/sachinchoolur/lightgallery.js/blob/HEAD/img/img2.jpg">
<img src="https://raw.githubusercontent.com/sachinchoolur/lightgallery.js/HEAD/img/thumb2.jpg">
</a>
...
</div>
Finally you need to initiate the gallery by adding the following code.
<script>
lightGallery(document.getElementById('lightgallery'));
</script>
If you like lightgallery please support the project by staring the repository or tweet about this project.
If you want to use lightgallery.js to develop commercial sites, themes, projects, and applications, the Commercial license is the appropriate license. With this option, your source code is kept proprietary. Purchase a lightgallery.js Commercial License at uplabs.com/posts/lightgallery-js
If you are creating an open source application under a license compatible with the GNU GPL license v3, you may use this project under the terms of the GPLv3.