Better Image Placeholders with ThumbHash

Depending on the network speed and image size, loading images may be slow. This could make the page design look ugly, lead to content shifts, and create bad UX. One way to eliminate this problem is to use image placeholders. We can load very small blurred versions of our images and display them first (using the same size as the original images) while continue loading bigger images. Introducing the ThumbHash. A very compact representation of a placeholder for an image. Store it inline with your data and show it while the real image is loading for a smoother loading experience. It's similar to BlurHash but with the following advantages: Encodes more detail in the same space Also encodes the aspect ratio Gives more accurate colors Supports images with alpha We can create the ThumbHash for an image using the thumbhash library or thumbhash-gen command-line utility. For example, to create the ThumbHash for the image above, we will need one command: npx thumbhash-gen https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aj3ukzipq9acckn8a9ux.jpg The result will be a compact hash string XakJJYI/WFWSaGZ1d/ZXdnlw5gdn which we can use as a placeholder. One option is to use a "special" component that supports the ThumbHash format. For example, the nextjs-thumbhash and Expo Image. const imageUrl = 'https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aj3ukzipq9acckn8a9ux.jpg' const thumbhash = 'XakJJYI/WFWSaGZ1d/ZXdnlw5gdn' ... Another option will be to get the "URL data" from ThumbHash using the thumbhash library: const thumbhash = 'XakJJYI/WFWSaGZ1d/ZXdnlw5gdn' const urlData = thumbhash.thumbHashToDataURL(Buffer.from(thumbhash, 'base64')) // urlData -> 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAA...' And use it as the src attribute for the image: That's it!

Apr 14, 2025 - 16:04
 0
Better Image Placeholders with ThumbHash

Depending on the network speed and image size, loading images may be slow. This could make the page design look ugly, lead to content shifts, and create bad UX.

One way to eliminate this problem is to use image placeholders. We can load very small blurred versions of our images and display them first (using the same size as the original images) while continue loading bigger images.

Cute kitten

Small blurred version

Introducing the ThumbHash.

A very compact representation of a placeholder for an image. Store it inline with your data and show it while the real image is loading for a smoother loading experience. It's similar to BlurHash but with the following advantages:

  • Encodes more detail in the same space
  • Also encodes the aspect ratio
  • Gives more accurate colors
  • Supports images with alpha

We can create the ThumbHash for an image using the thumbhash library or thumbhash-gen command-line utility. For example, to create the ThumbHash for the image above, we will need one command:

npx thumbhash-gen https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aj3ukzipq9acckn8a9ux.jpg

The result will be a compact hash string XakJJYI/WFWSaGZ1d/ZXdnlw5gdn which we can use as a placeholder.

One option is to use a "special" component that supports the ThumbHash format. For example, the nextjs-thumbhash and Expo Image.

const imageUrl = 'https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aj3ukzipq9acckn8a9ux.jpg'
const thumbhash = 'XakJJYI/WFWSaGZ1d/ZXdnlw5gdn'

...

<Image
  src={imageUrl}
  thumbhash={thumbhash}
/>

Another option will be to get the "URL data" from ThumbHash using the thumbhash library:

const thumbhash = 'XakJJYI/WFWSaGZ1d/ZXdnlw5gdn'
const urlData = thumbhash.thumbHashToDataURL(Buffer.from(thumbhash, 'base64'))
// urlData -> 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAA...'

And use it as the src attribute for the image:

 src={urlData} />

That's it!