photoswipe vs viewerjs vs glightbox vs magnific-popup vs lightbox2 vs lightgallery.js
Choosing the Right Image Lightbox and Gallery Library
photoswipeviewerjsglightboxmagnific-popuplightbox2lightgallery.jsSimilar Packages:

Choosing the Right Image Lightbox and Gallery Library

These libraries provide overlay interfaces for viewing images and media content without leaving the current page. They handle common tasks like zooming, navigating between items, and displaying captions. While they share a core purpose, they differ significantly in dependencies, mobile gesture support, content flexibility, and maintenance status. Some are lightweight and modern, while others are legacy tools that rely on jQuery or offer specialized features like inline HTML content.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
photoswipe549,23925,2721.21 MB1712 years agoMIT
viewerjs101,9858,244669 kB19 days agoMIT
glightbox71,2412,536401 kB472 years agoMIT
magnific-popup63,20011,3001.05 MB6792 years agoMIT
lightbox226,9526,373946 kB517 months ago-
lightgallery.js05,317611 kB4-GPLv3

Image Lightbox Libraries: Architecture, Features, and Trade-offs

When adding image galleries to a web application, developers often reach for a lightbox library to handle the overlay, navigation, and zoom interactions. The six packages compared here — glightbox, lightbox2, lightgallery.js, magnific-popup, photoswipe, and viewerjs — all solve this problem but take different approaches to initialization, content support, and mobile interaction. Understanding these differences helps you avoid over-engineering simple tasks or under-delivering on complex requirements.

🛠️ Initialization and Dependencies

How you set up the library affects your bundle size and framework compatibility. Some libraries work with vanilla JavaScript, while others require jQuery or specific DOM structures.

glightbox is vanilla JavaScript with no external dependencies. It initializes by selecting elements and passing options to a constructor.

import GLightbox from 'glightbox';

const lightbox = GLightbox({
  selector: '.my-gallery-links',
  zoomable: true
});

lightbox2 relies on jQuery and initializes automatically based on rel or data-lightbox attributes in your HTML. You configure it globally via an options object.

import $ from 'jquery';
import 'lightbox2';

lightbox.option({
  'albumLabel': 'Image %1 of %2',
  'wrapAround': true
});

lightgallery.js uses a modular vanilla JavaScript approach. You attach it to a specific container element and can load plugins dynamically.

import lightGallery from 'lightgallery';

const $gallery = document.getElementById('my-gallery');
lightGallery($gallery, {
  speed: 500,
  thumbnail: true
});

magnific-popup is a jQuery plugin. You initialize it by selecting the trigger elements and calling the method on the jQuery object.

import $ from 'jquery';
import 'magnific-popup';

$('.image-link').magnificPopup({
  type: 'image',
  gallery: { enabled: true }
});

photoswipe (v5) separates the core logic from the UI. You initialize a lightbox wrapper that handles events and DOM creation.

import PhotoSwipeLightbox from 'photoswipe/lightbox';

const lightbox = new PhotoSwipeLightbox({
  gallery: '#my-gallery',
  children: 'a',
  pswpModule: () => import('photoswipe')
});
lightbox.init();

viewerjs focuses on a single image or a container of images. It initializes on a specific DOM node to provide viewing tools.

import Viewer from 'viewerjs';

const image = document.getElementById('image');
const viewer = new Viewer(image, {
  toolbar: { zoom: 1, rotate: 1 }
});

🎬 Content Support: Images, Video, and HTML

Not all lightboxes handle non-image content equally. Some are strictly for photos, while others support video embeds or arbitrary HTML.

glightbox supports images, YouTube, Vimeo, and inline HTML content out of the box. You define the type via data attributes.

<a href="video.mp4" data-glightbox="type: video">
  Watch Video
</a>

lightbox2 is primarily designed for static images. Supporting other content types requires significant workarounds or is not supported officially.

<a href="image.jpg" data-lightbox="roadtrip">
  View Image
</a>

lightgallery.js handles images and videos via plugins. You must include the video plugin to support YouTube or Vimeo links.

import lgVideo from 'lightgallery/plugins/video';

lightGallery($gallery, {
  plugins: [lgVideo]
});

magnific-popup excels at displaying inline HTML, AJAX content, and iframes, not just images. This makes it useful for login forms or dynamic content in overlays.

$('.popup-inline').magnificPopup({
  type: 'inline',
  midClick: true
});

photoswipe is optimized for images but supports video content through custom slide implementations. It requires more code to set up non-image slides compared to others.

// Photoswipe v5 uses slide objects
const slides = [
  { src: 'image.jpg', w: 1000, h: 800 },
  { src: 'video.mp4', type: 'video' }
];

viewerjs is strictly for image viewing. It does not support video or arbitrary HTML content within the viewer canvas.

<div id="viewer">
  <img src="photo1.jpg">
  <img src="photo2.jpg">
</div>

📱 Touch Gestures and Mobile Experience

Mobile users expect smooth pinch-to-zoom and swipe navigation. Libraries differ in how much of this is built-in versus what you must implement yourself.

glightbox includes touch support for swiping and zooming without extra configuration. It works well on mobile devices immediately after setup.

const lightbox = GLightbox({
  touchNavigation: true,
  loop: true
});

lightbox2 has basic touch support but feels dated on modern high-DPI screens. It lacks advanced gesture handling like multi-touch zoom.

lightbox.option({
  'fadeDuration': 300,
  'resizeDuration': 200
});

lightgallery.js offers robust touch gestures including pinch-to-zoom and swipe. You can adjust sensitivity via options.

lightGallery($gallery, {
  mobileSettings: {
    controls: false,
    showCloseIcon: true
  }
});

magnific-popup supports touch navigation but relies on jQuery mobile events. It may feel less fluid compared to modern vanilla JS alternatives.

$('.gallery').magnificPopup({
  type: 'image',
  mainClass: 'mfp-with-zoom'
});

photoswipe provides the best-in-class gesture engine. It handles momentum scrolling and pinch-zoom with high precision, but requires correct image dimensions.

const lightbox = new PhotoSwipeLightbox({
  pinchToClose: true,
  closeOnVerticalDrag: true
});

viewerjs focuses on image manipulation gestures like rotation and flipping rather than gallery swiping. It is ideal for inspecting details.

const viewer = new Viewer(image, {
  movable: true,
  zoomable: true,
  rotatable: true
});

🎨 Customization and Theming

Projects often require custom branding. Some libraries use CSS classes that are easy to override, while others rely on JavaScript options for UI control.

glightbox uses standard CSS classes that are easy to target. You can disable specific UI elements via options.

const lightbox = GLightbox({
  skin: 'clean',
  closeButton: true
});

lightbox2 requires editing the CSS file directly or overriding styles with high specificity. It offers limited JS options for UI changes.

.lb-data .lb-caption {
  color: #fff;
  font-size: 14px;
}

lightgallery.js is highly modular. You can enable or disable counters, thumbnails, and share buttons via plugins.

import lgThumbnail from 'lightgallery/plugins/thumbnail';

lightGallery($gallery, {
  plugins: [lgThumbnail],
  showThumbByDefault: false
});

magnific-popup allows deep customization through callbacks and markup options. You can rewrite the entire popup structure in JS.

$('.popup').magnificPopup({
  mainClass: 'my-custom-class',
  removalDelay: 300
});

photoswipe gives you full control over the DOM structure. You can build a custom UI on top of the core engine if needed.

// Custom UI implementation requires extending the base class
// or using the provided CSS and overriding variables

viewerjs provides a toolbar configuration object to show or hide specific tools like download, rotate, or reset.

const viewer = new Viewer(image, {
  toolbar: {
    oneToOne: true,
    reset: true,
    rotate: true
  }
});

🤝 Similarities: Shared Ground Between Libraries

Despite their differences, these libraries share common goals and patterns. Here are key overlaps:

1. 🖼️ Core Overlay Functionality

  • All libraries create a modal overlay to focus attention on content.
  • They handle z-index management and background dimming automatically.
// All libraries essentially do this internally:
// overlay.style.display = 'block';
// content.style.zIndex = '9999';

2. ⌨️ Keyboard Navigation

  • Most support ESC to close and arrow keys to navigate.
  • This is critical for accessibility and desktop usability.
// Typical keyboard listener pattern
document.addEventListener('keydown', (e) => {
  if (e.key === 'Escape') closeLightbox();
});

3. 📷 Image Preloading

  • Libraries preload next/previous images to ensure smooth transitions.
  • This prevents blank screens when users click quickly.
// Internal logic typically looks like:
const nextImg = new Image();
nextImg.src = nextSlideSource;

4. 📱 Responsive Behavior

  • All adjust layout based on viewport size.
  • They hide or resize controls on smaller screens.
// CSS Media Query usage common across all
@media (max-width: 768px) {
  .lightbox-controls { display: none; }
}

5. 🔌 Event Hooks

  • All provide callbacks for open, close, and change events.
  • This allows integration with analytics or lazy loading.
// Example callback pattern
lightbox.on('open', () => {
  console.log('Gallery opened');
});

📊 Summary: Feature Comparison

Featureglightboxlightbox2lightgallery.jsmagnific-popupphotoswipeviewerjs
DependenciesNonejQueryNonejQueryNoneNone
Video Support✅ Native❌ No✅ Plugin✅ Native⚠️ Custom❌ No
Inline HTML✅ Yes❌ No⚠️ Plugin✅ Native❌ No❌ No
Touch Gestures✅ Good⚠️ Basic✅ Good⚠️ Basic✅ Excellent✅ Tools
Maintenance✅ Active⚠️ Legacy✅ Active⚠️ Legacy✅ Active✅ Active
Primary UseGeneral GallerySimple ImagesComplex GalleryContent PopupHigh Perf GalleryImage Inspector

💡 The Big Picture

glightbox is like a reliable Swiss Army knife 🔪 — it covers most needs without requiring extra tools. It is the safest default choice for modern projects that need video and images without jQuery.

lightbox2 is like an old film camera 📷 — it works, but it shows its age. Use it only if you are stuck maintaining older jQuery codebases.

lightgallery.js is like a modular stereo system 🎵 — you can add components as needed. Perfect for teams that want to trim unused features from their bundle.

magnific-popup is like a multi-purpose display screen 🖥️ — great for showing forms or AJAX content, not just photos. Ideal for jQuery apps needing flexible popups.

photoswipe is like a professional lens 🔭 — it offers the clearest, smoothest view but requires more setup. Best for photography portfolios where image quality and gestures matter most.

viewerjs is like a magnifying glass 🔍 — designed for inspecting details rather than browsing. Choose it when users need to rotate or analyze specific images.

Final Thought: For most new projects, glightbox or photoswipe will serve you best. glightbox wins on ease of use, while photoswipe wins on performance. Avoid lightbox2 and magnific-popup unless you have specific legacy or jQuery requirements.

How to Choose: photoswipe vs viewerjs vs glightbox vs magnific-popup vs lightbox2 vs lightgallery.js

  • photoswipe:

    Choose photoswipe if performance and touch gesture accuracy are your top priorities, especially for mobile-heavy applications. It requires more setup to implement the UI, but it offers the smoothest pinch-to-zoom and swipe experience available.

  • viewerjs:

    Choose viewerjs if you need image inspection tools like rotation, flipping, and advanced zoom controls rather than a slideshow gallery. It is designed for viewing individual images in detail, similar to a document viewer, rather than browsing a collection.

  • glightbox:

    Choose glightbox if you want a modern, dependency-free solution that works out of the box with minimal configuration. It supports video and iframes natively and is ideal for projects that need a balance of features and simplicity without bundling heavy libraries.

  • magnific-popup:

    Choose magnific-popup if your project requires displaying inline HTML content, AJAX responses, or iframes alongside images. It is a strong choice for jQuery-based applications that need a flexible content popup rather than just a photo gallery.

  • lightbox2:

    Choose lightbox2 only if you are maintaining a legacy jQuery project or need an extremely basic image overlay with zero configuration. It is not recommended for new development due to its age and reliance on jQuery, which adds unnecessary weight to modern stacks.

  • lightgallery.js:

    Choose lightgallery.js if you need a modular architecture where you can import only the features you need, such as thumbnails or zoom. It is well-suited for complex galleries that require deep customization and extensive plugin support.

README for photoswipe

Stand With Ukraine

PhotoSwipe v5 — JavaScript image gallery and lightbox

Demo | Documentation

Sponsor via OpenCollective Follow on Twitter

Repo structure

  • dist/ - main JS and CSS
  • src/ - source JS and CSS.
    • src/js/photoswipe.js - entry for PhotoSwipe Core.
    • src/js/lightbox/lightbox.js - entry for PhotoSwipe Lightbox.
  • docs/ - documentation markdown files.
  • demo-docs-website/ - website with documentation, demos and manual tests.
  • build/ - rollup build config.

To build JS and CSS in dist/ directory, run npm run build.

To run the demo website and automatically rebuild files during development, run npm install in demo-docs-website/ and npm run watch in the root directory.

Older versions

Documentation for the old version (v4) can be found here and the code for 4.1.3 is here.


This project is tested with BrowserStack.