1001Ferramentas
🌫️ Generators

BlurHash Generator

Generate a compact BlurHash string from an image to use as a blurred placeholder in apps and sites while the image loads.

BlurHash: compact image placeholders for the modern web

BlurHash is a compact representation of a placeholder for an image. Created by Dag Γ…gren at Wolt in 2019, it encodes a blurred preview of any picture into a tiny string of roughly 20–30 characters that you can ship alongside image metadata. When the page loads, the browser decodes the hash into a colorful, blurred canvas while the full image streams over the network β€” turning a grey skeleton into a meaningful preview.

The format is based on a small 2D Discrete Cosine Transform (DCT). Only the lowest-frequency components are kept, quantized and packed using a custom base83 alphabet that survives JSON, URLs and HTML attributes without escaping. A typical 4Γ—3 component hash like LEHV6nWB2yk8pyo0adR*.7kCMdnj takes around 28 bytes β€” orders of magnitude smaller than a base64 thumbnail.

Why bother with a placeholder hash?

  • Avoid Cumulative Layout Shift (CLS): the placeholder occupies the final aspect ratio from the first paint, protecting your Core Web Vitals.
  • Perceived performance: a colorful blur feels meaningfully faster than a grey rectangle, especially on slow connections.
  • Aesthetic continuity: dominant colors are preserved, so the transition from placeholder to full image feels natural.
  • Tiny payload: the hash fits into a database column or GraphQL field with negligible overhead.

How the pipeline works

The standard production flow is: encode server-side at upload, store the string in your database next to the image URL, and decode client-side while the real asset loads.

// Node.js encode (sharp + blurhash)
import sharp from 'sharp'
import { encode } from 'blurhash'
const { data, info } = await sharp(buffer)
  .raw().ensureAlpha()
  .resize(32, 32, { fit: 'inside' })
  .toBuffer({ resolveWithObject: true })
const hash = encode(new Uint8ClampedArray(data), info.width, info.height, 4, 3)

The two trailing numbers (4, 3) are the X and Y component counts. More components capture more detail but produce a longer string. The default 4Γ—3 is the sweet spot for landscape thumbnails; portrait images often use 3Γ—4.

BlurHash vs LQIP, SQIP and CSS blur

  • LQIP (Low Quality Image Placeholder): a tiny 8Γ—8 JPEG encoded as data: URL. Works everywhere, but ~400 bytes vs ~30 bytes for BlurHash.
  • SQIP (SVG QIP): vectorized primitives by Tobias Baldauf β€” visually striking, but heavier and harder to cache.
  • CSS filter: blur() on a tiny preview <img>: simple, but you still need to load some image data.
  • BlurHash: pure string, decoded by a few KB of JavaScript into a canvas.

Ecosystem and adoption

Official reference implementations exist for JavaScript/TypeScript, Swift, Kotlin, Python, PHP, Rust, Go, Java and C#. The technique is used in production by Wolt, Mastodon, Signal and many image CDNs. Cloudinary and Imgix expose BlurHash as a derived attribute on uploaded assets, so you do not even need to run the encoder yourself.

FAQ

Is BlurHash production-ready? Yes β€” it has been deployed at scale since 2019 by Wolt, Signal, Mastodon and many photo-heavy products.

What is the ideal hash length? 20–30 characters covers the vast majority of cases. Going beyond 40 characters rarely improves perceived quality and inflates payload.

How much detail does it preserve? Only the gist: dominant colors and broad gradients. Sharp edges, text and faces are intentionally blurred away β€” that is the whole point.

Is there a successor? Yes β€” ThumbHash, by Evan Wallace, improves quality and adds alpha-channel support. BlurHash remains an excellent, mature choice.

What about performance? Decoding a 4Γ—3 hash to a 32Γ—32 canvas takes around 5 ms on a mid-range mobile device. The result can then be upscaled by CSS without any extra cost.

Related Tools