React Image and Lazy-Loading Libraries

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production.

See the section bibliography for the reference material consulted while preparing these pages.

Baseline date: 2026-10-07. Versions are the latest on npm on that date. Since browsers lazy-load natively, most of these libraries are now optional. This page says what each does, how active it is and what to use instead. The React fundamentals are in the React section, and the native attributes are in native HTML images.

The native baseline

export function Cover({ src, srcSet, alt, width, height }: CoverProps) {
  return (
    <img src={src} srcSet={srcSet} sizes="(min-width: 60em) 20vw, 50vw"
         alt={alt} width={width} height={height} loading="lazy" decoding="async" />
  );
}

React passes loading, decoding and fetchPriority straight to the DOM. For the LCP image, drop loading="lazy". That covers lazy loading, responsive sources and layout shift without a dependency. What it lacks is a fallback chain, a custom trigger distance and a built-in effect, which is what the libraries add.

react-lazyload

react-lazyload (3.2.1) wraps content in a LazyLoad component that renders it when it scrolls near the viewport.

import LazyLoad from 'react-lazyload';

<LazyLoad height={300} offset={200} once placeholder={<div className="skeleton" />}>
  <img src={url} alt={alt} width={200} height={300} />
</LazyLoad>

It works with any content, not only images, and it uses scroll listeners rather than an IntersectionObserver by default. Activity is low. Prefer native lazy loading for images, or IntersectionObserver for other content.

react-image

react-image (4.1.0) offers an Img component and a useImage hook with a list of sources to try in order, and loader and fallback elements. It has not had a release since 2023.

import { useImage } from 'react-image';

function Cover({ srcList }: { srcList: string[] }) {
  const { src, isLoading, error } = useImage({ srcList, useSuspense: false });
  if (isLoading) return <div className="skeleton" />;
  if (error) return <div className="no-cover">No cover</div>;
  return <img src={src} alt="" />;
}

The fallback chain is useful for user avatars (try the user’s image, then a generated one). It does not do responsive images: it picks one URL, so you lose srcset. Verify that the version still works with your React major version.

react-lazy-load-image-component

react-lazy-load-image-component (1.6.3) provides LazyLoadImage with a built-in placeholder, an effect (blur, black and white, opacity), and a trackWindowScroll HOC for many images in a scrolling container.

import { LazyLoadImage } from 'react-lazy-load-image-component';
import 'react-lazy-load-image-component/src/effects/blur.css';

<LazyLoadImage src={url} alt={alt} width={200} height={300} effect="blur" placeholderSrc={tinyUrl} />

The blur effect shows the image blurred while the file loads, and a placeholderSrc can be a small image or a data URL decoded from a BlurHash, see BlurHash in the browser.

A small IntersectionObserver hook

When you need to control the trigger (a carousel, an infinite list, a video), a hook is a dozen lines and has no dependency:

import { useEffect, useRef, useState } from 'react';

export function useInView<T extends Element>(rootMargin = '200px') {
  const ref = useRef<T>(null);
  const [inView, setInView] = useState(false);
  useEffect(() => {
    const node = ref.current;
    if (!node) return;
    const observer = new IntersectionObserver(([entry]) => {
      if (entry.isIntersecting) { setInView(true); observer.disconnect(); }
    }, { rootMargin });
    observer.observe(node);
    return () => observer.disconnect();
  }, [rootMargin]);
  return [ref, inView] as const;
}

Which to use

Option Status Needed? When to choose it

Native loading="lazy" and srcset

Browser feature

Default

Almost always. No dependency, responsive images, works with SSR.

react-lazyload 3.2.1

Low activity

Rarely

Lazy-rendering non-image components with a scroll container, if you are already using it.

react-image 4.1.0

No release since 2023

Sometimes

Fallback chains for user-provided images. Check compatibility with your React version.

react-lazy-load-image-component 1.6.3

Check the repository for recent activity

Sometimes

A ready-made blur or opacity effect over the placeholder, with minimal code.

IntersectionObserver hook

Browser feature

When native is not enough

Custom triggers and non-image content.

next/image or a framework image component

Maintained with the framework

In Next.js apps

See Next.js Image.

Whatever you choose, give every image width and height (or an aspect ratio) and use an optimised format. The libraries only decide when to load.