# lightGallery: A Modular Lightbox Gallery for React, Vue and Angular

> lightGallery is a dependency-free TypeScript lightbox plugin with a plugin-based architecture, a GPLv3 and commercial dual licence, and a licence key requirement for paid use. This review covers how it installs, how the plugin system works, and where it stops being the right choice.

**sachinchoolur/lightGallery** — A customizable, modular, responsive, lightbox gallery plugin. 

- Repository: https://github.com/sachinchoolur/lightGallery
- Website: https://www.lightgalleryjs.com/
- Stars: 7,052 · Forks: 1,294
- Language: TypeScript
- License: NOASSERTION
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/sachinchoolur-lightgallery

## What lightGallery solves, and who it is actually for

A lightbox is a small problem with a long tail. You have a grid of thumbnails, and you want a click to open the full image over the page, with keyboard navigation, swipe gestures on touch devices, and a way back. The hard parts are not the overlay. They are the gesture handling, the preloading, the history API integration, and the video embed support that people ask for after the first version ships.

lightGallery targets that second stage. The README describes it as a "customizable, modular, responsive, lightbox gallery plugin" with no dependencies, available for React.js, Angular, Vue.js and TypeScript. The repository layout backs that up: alongside src/ and dist/ there are lightgallery-react/, lightgallery-vue/, lightgallery-angular/ and lightgallery-lit/ directories, so the framework wrappers are maintained in the same repository rather than as separate community projects.

The intended user is a front-end engineer who already has markup and wants a viewer on top of it. The README is explicit that lightGallery "does not force you to use any kind of markup." That matters if you are retrofitting a gallery onto an existing CMS template, where you cannot restructure the DOM to fit a component's expectations.

It is not aimed at someone who wants a drag-and-drop gallery builder. There is no admin UI, no upload pipeline and no storage layer. It is the viewing layer only.

## The plugin architecture and what the data flow looks like

The core module handles the overlay, transitions and navigation. Everything else is a plugin you opt into at initialization. The README lists the available names: lgZoom, lgAutoplay, lgComment, lgFullscreen, lgHash, lgPager, lgRotate, lgShare, lgThumbnail, lgVideo and lgMediumZoom.

That split has a real consequence. If you do not pass a plugin in the settings object, its code is not part of your bundle. The README links a bundlephobia tree-shaking badge, which is the project's own signal that this is a design goal rather than an accident. For a page that only needs a basic image viewer, you can skip thumbnails, zoom and video entirely.

The data flow is straightforward. You give lightGallery a container element and an options object. It reads the anchor elements inside that container, using the href as the full-size source and the nested img as the thumbnail. If you supply data-lg-size="${width}-${height}" on an anchor, the plugin knows the original dimensions and can animate the zoom from the thumbnail position. The README calls this "completely optional" and notes it is only needed for the initial zoom animation.

The settings object also carries speed, which the README's example sets to 500. That is milliseconds for the transition. Plugins are passed as an array of imported functions, so the coupling between your code and the plugin is explicit at the call site.

One structural detail worth noting: the repository has a plugins-config-rollup.json at the top level, and the build script runs rollup against rollup.config.ts. The plugins are separate build outputs, not just separate modules in one bundle. That is consistent with the per-plugin CSS files the README tells you to include.

## Installing lightgallery from npm and wiring a first gallery

The README lists NPM, Yarn, Bower, CDNs and GitHub as installation routes. For a bundler-based project, npm is the shortest path:

```bash
npm install lightgallery
```

After that, import the core and only the plugins you need. The README gives this exact import pattern:

```javascript
import lightGallery from 'lightgallery';

// Plugins
import lgThumbnail from 'lightgallery/plugins/thumbnail'
import lgZoom from 'lightgallery/plugins/zoom'
```

Note the import paths: they are lightgallery/plugins/thumbnail and lightgallery/plugins/zoom, not paths under dist/. The package.json declares "files": ["dist"], and main points at dist/lightgallery.umd.js, so the published package resolves those subpaths through its own layout rather than through the src/ directory you see in the repository.

Your markup needs a container with anchors. The README's example uses a div with id="lightgallery" and anchors carrying data-lg-size:

```html
<div id="lightgallery">
    <a href="img/img1.jpg" data-lg-size="1600-2400">
        <img alt=".." src="img/thumb1.jpg" />
    </a>
    <a href="img/img2.jpg" data-lg-size="1024-800">
        <img alt=".." src="img/thumb2.jpg" />
    </a>
</div>
```

Then initialize it. The README's example passes plugins, speed and a licenseKey:

```javascript
lightGallery(document.getElementById('lightgallery'), {
    plugins: [lgZoom, lgThumbnail],
    speed: 500,
    licenseKey: 'your_license_key'
});
```

If you load lightGallery through a script tag instead of a bundler, the README says to reference the UMD build and the plugin UMD files in order, and to use the plugin names exactly as listed (lgZoom, lgThumbnail and so on) rather than the imported identifiers you would use with ES modules. Mixing the two conventions is a common source of confusion, because the names look almost identical.

The README also mentions that lightgallery-bundle.css contains the core styles plus all plugin styles, as an alternative to including lightgallery.css, lg-zoom.css and lg-thumbnail.css separately. For a first run, the bundle stylesheet removes one class of missing-style problems.

## The licence key is a hard gate, not a formality

This is the part that catches teams late. lightGallery is dual-licensed. The package.json declares "license": "GPLv3", and the README states that if you are creating an open source application under a licence compatible with the GNU GPL license v3, you may use the project under GPLv3 terms. For commercial sites, themes, projects and applications, the README points to a commercial licence, under which "your source code is kept proprietary."

GPLv3 is a copyleft licence. Using the library in a proprietary product without the commercial licence is the scenario the dual licensing exists to prevent, and the initialization example in the README includes licenseKey: 'your_license_key' as a normal setting. The README says you receive the key by email once you purchase a licence.

I am not giving legal advice here, and the practical boundary between "open source application" and "commercial site" is not something the README defines. What is clear is that the project expects a key for commercial use and that the key is passed at runtime through the settings object. If your build pipeline strips or omits that option, you should expect the licence question to surface later rather than disappear.

There is also a naming collision worth flagging for anyone searching for terms: the related searches include "Lightgallery login" and "Lightgallery app". Those do not describe this project. lightGallery has no login and no standalone app; it is a JavaScript plugin. The licence key is the only credential-like value involved.

## Where lightGallery is the wrong tool

The README's browser support claim is that lightGallery supports "all major browsers including IE 10 and above." That is a broad compatibility promise, and it comes with a cost in the shape of the library. The package.json declares a module field pointing at dist/lightgallery.es5.js, which is an ES5 output. If your project targets modern browsers only and you are already shipping ES2017 or later, you are carrying transpiled output you do not need.

The bigger limitation is scope. lightGallery is a viewer. If your requirement is a gallery with server-side image processing, responsive srcset generation, EXIF handling or a searchable media library, none of that is in this repository. You would be pairing lightGallery with something else, and at that point the integration work may exceed the value of the lightbox itself.

There is also a dependency-free claim that deserves a caveat. The README says "No dependencies," and package.json shows no dependencies field in the excerpt available. But the build toolchain is substantial: rollup, sass, cleancss, eslint, tslint, nodemon and rimraf all appear in the scripts. "No dependencies" describes the runtime bundle, not the development environment. Installing the repository to build from source pulls in a much larger tree than the published package does.

Finally, the README does not document rollback or downgrade procedures between major versions. If you pin to 2.9.0 and later need to move back, the documentation gives you nothing to work from.

## lightGallery against PhotoSwipe: different jobs

The related searches include "lightgallery alternative" and the search questions include "lightgallery vs photoswipe", so the comparison is one people actually make. The difference is architectural.

PhotoSwipe is built around a core viewer with a documented API and a smaller built-in feature surface; you add behaviour yourself. lightGallery ships the behaviour as named plugins you switch on. Video support for YouTube, Vimeo, Wistia and HTML5 is a plugin in lightGallery, not something you wire up. Social sharing, rotation, fullscreen, autoplay and browser history deep linking are likewise plugins.

That means lightGallery gets you to a feature-complete gallery faster, and PhotoSwipe gives you a smaller surface to reason about. The trade-off shows up in bundle size and in how much of the library's behaviour you are opting out of. With lightGallery, opting out is a matter of not importing a plugin. With a leaner core, opting in is a matter of writing the code.

The licence difference is the other axis, and it is the one that usually decides the question. lightGallery's GPLv3 and commercial dual licence is a real constraint for closed-source products. If your organisation cannot accept that, the plugin architecture does not matter, because you will not be shipping it.

If you are already inside a framework wrapper, note that lightGallery maintains React, Vue, Angular and Lit wrappers in this repository. The README links separate documentation pages for React, Vue.js and Angular. That is a meaningful difference from libraries where the framework binding is a third-party package with its own release cadence.

## Maintenance signals and what upgrading costs

The repository is not archived, and the last push was on 2026-09-21. The most recent release listed is 2.9.0 from 2025-10-01, following 2.9.0-beta.1 in June 2025 and 2.8.3 in March 2025. The release cadence over that window is roughly one significant release per quarter, with a beta phase before the 2.9.0 line.

That pattern tells you something practical: minor versions arrive with beta pre-releases, so there is a window to test before a stable tag. If you depend on lightGallery in production, tracking the beta is a cheaper way to find breakage than discovering it after the stable release.

The upgrade cost is concentrated in two places. First, plugin imports: because plugins are separate entry points (lightgallery/plugins/thumbnail, lightgallery/plugins/zoom), a change to a plugin's module path breaks your build rather than degrading gracefully. Second, stylesheets: the README supports both a bundle stylesheet and per-plugin stylesheets, and if you use the per-plugin route, a new plugin means a new CSS import in your head or your bundler entry.

The version in package.json is 2.9.0, matching the latest release. The engines field declares node >=6.0.0, which is a floor for the build tooling rather than a runtime requirement, since the published artifact is browser JavaScript.

On licence cost: the README does not publish pricing, and there is no figure to give here. What it does say is that the key arrives by email after purchase and is passed through the licenseKey setting. Budget for the purchase decision as part of adoption, not as a later cleanup task.

## Conclusion

Adopt lightGallery if you need a lightbox with video, thumbnails, zoom and hash-based deep linking, and you can accept the licence key requirement for commercial work. Do not adopt it if you want a permissively licensed library you can modify without restriction, or if you are building a full gallery product rather than a viewer layer. Before you commit, verify two things: whether the plugins you need are covered by the licence you intend to buy, and whether the markup you already have matches the data-lg-size attribute pattern the initial zoom animation expects.

## FAQ

### How do I use lightGallery in a project?

Install it with npm install lightgallery, import the core plus whichever plugins you need, then call lightGallery on a container element with a settings object. The README's example passes plugins, speed and a licenseKey, and the container holds anchors whose href points at the full-size media.

### Is lightGallery free?

It is dual-licensed. The README states that open source applications under a GPLv3-compatible licence may use it under GPLv3 terms, while commercial sites, themes, projects and applications require a commercial licence, with a key delivered by email after purchase.

### What is the lightGallery licence?

The package.json declares GPLv3, and the README describes a commercial licence option under which your source code stays proprietary. The commercial route is the one the README points to for commercial sites, themes, projects and applications.

### How does lightGallery compare with PhotoSwipe?

lightGallery ships its behaviour as named plugins such as lgZoom, lgThumbnail and lgVideo that you enable at initialization, so more features are available without extra code. A leaner core gives you a smaller surface but expects you to write the behaviour yourself. The licence terms also differ, and that is often the deciding factor.

### What does lightgallery is not defined mean?

It usually means the script has not loaded or the global is not available when your initialization code runs. When loading via script tag, the README says to include lightgallery.umd.js first and then the plugin UMD files after it, in that order.

## Sources

- [Issues](https://github.com/sachinchoolur/lightGallery/issues)
- [Project website](https://www.lightgalleryjs.com/)
- [README](https://github.com/sachinchoolur/lightGallery/blob/master/README.md)
- [Releases](https://github.com/sachinchoolur/lightGallery/releases)
- [sachinchoolur/lightGallery on GitHub](https://github.com/sachinchoolur/lightGallery)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/sachinchoolur-lightgallery
