Skip to content

Justified Gallery

Elegant, Professional, Endless.

Justified Gallery is a zero-dependency JavaScript library, written in TypeScript, that lets you create a high quality justified gallery of images. It works with plain HTML, React, Vue, or any other framework.

It solves a common problem for people who build websites: you have a series of images to display, but you are not sure how to arrange them elegantly. Important websites such as 500px, Flickr, or Google display images in an excellent way, justifying them similarly to a brick wall. Justified Gallery gives you the power to do that too.

Justified Gallery is a professional and open source library that even 500px, one of the best photography social networks, chose to display its images!

Terminal window
npm install justified-gallery

Justified Gallery works on standard markup: a container with a series of links, each with a thumbnail inside and pointing to the original image.

<div id="gallery" class="justified-gallery">
<a href="path/to/image1.jpg">
<img alt="Title 1" src="path/to/image1_thumbnail.jpg" />
</a>
<a href="path/to/image2.jpg">
<img alt="Title 2" src="path/to/image2_thumbnail.jpg" />
</a>
<!-- other images... -->
</div>

Justified Gallery also accepts other input formats, to better fit your needs.

Import the library and its stylesheet, create a gallery on the container and initialize it. It’s a plain class with zero dependencies and TypeScript types included, so it fits any stack:

import { JustifiedGallery } from 'justified-gallery';
import 'justified-gallery/style.css';
const container = document.getElementById('gallery')!;
const settings = { rowHeight: 160 };
const gallery = new JustifiedGallery(container, settings);
gallery.init();

Note the justified-gallery class already on the container: the stylesheet uses it to hide the gallery until it’s laid out, avoiding a flash of unstyled images.

Continue with the Getting Started guide, or jump straight to the React or Vue guide.

TypeScript types included

Works everywhere

Zero dependencies and a tiny API: a plain class on a real DOM element. Use it in vanilla JS, React, Vue or any other framework, no wrapper needed.
import { JustifiedGallery } from 'justified-gallery';
import 'justified-gallery/style.css';
const container = document.getElementById('gallery')!;
const gallery = new JustifiedGallery(container);
gallery.init();
const containerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const gallery = new JustifiedGallery(containerRef.current!);
gallery.init();
return () => gallery.destroy();
}, []);
return <div ref={containerRef}>{images}</div>;
const container = ref<HTMLDivElement>();
let gallery: JustifiedGallery | undefined;
onMounted(() => {
gallery = new JustifiedGallery(container.value!);
gallery.init();
});
onBeforeUnmount(() => gallery?.destroy());

Lightbox friendly

Plays nicely with GLightbox, PhotoSwipe and friends, with link attributes and lazy-loading-safe sources handled for you.

Automatic captions

Captions generated from your images’ alt or title attributes, or written in your own markup, and fully styleable.

Don't miss a pixel

An advanced justification algorithm sizes every row to fill the available width without ever cropping or distorting your images.

The right thumbnail, automatically

Loads (and hot-swaps) the best thumbnail size for each image, so you never download more pixels than needed and never see a blurry upscale.

Fast, progressive rendering

Non-blocking, row-by-row fade-in as thumbnails load, with a built-in spinner while the gallery grows.

Truly responsive

Watches the gallery’s own container width — not just the window — so it adapts to sidebars, flex layouts and anything else that resizes it.

Your rows, your rules

Six last-row behaviors, row height and margin controls, RTL support and many more options to build exactly the gallery you want.

Endless scroll ready

Build an infinite wall of images: append new entries and notify the gallery — new rows justify without rebuilding what’s already placed.

Events & clean teardown

Lifecycle events for every row and layout pass, plus a destroy method that cleans up your markup — ideal for single-page apps.

Dynamic galleries

Sort, randomize or filter the entries, append new images, and rebuild the gallery whenever your data changes.

Flexible input, silent errors

Links, divs or figures, images or inline SVG — and broken images are skipped gracefully, without breaking the layout.

1.7k
GitHub stars
296
Forks
124
Open issues
210
Closed issues
Monthly npm downloads (last 24 months), combined across justified-gallery and legacy justifiedGallery
Monthly npm downloads (last 24 months)

Justified Gallery is built with help from these contributors:

Some examples of uses of this library:

This is an open source project, released under the MIT license. You can help it grow in various ways: talking about it in blogs and social networks, starring the repository, or contributing your own features with a pull request.

If you have any issue, please post your question on the GitHub issues page, where you may also find existing answers.