blurhash-rs

A pure Rust implementation of the Blurhash algorithm for compact image placeholder strings.

Library
Cargo
v0.2.3
69stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
34/100Needs Attention
Development Activity0
Maintenance20
Community44
Maturity60
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
69/100Good
Architecture75
Code Quality78
Innovation68
Learning Curve55

blurhash-rs is a pure Rust implementation of the Blurhash algorithm originally developed by Wolt for encoding images into compact placeholder strings. Given an RGBA pixel buffer, it produces a ~20-30 character ASCII string that decodes back into a low-resolution, blurred approximation of the original image, useful for progressive image loading, content placeholders, and mild content obscuring.

The crate exposes a minimal core API (encode/decode) plus optional integrations behind Cargo feature flags for the image crate and GTK’s gdk-pixbuf, so callers can work with whichever image type they already have on hand. A default-enabled fast-linear-to-srgb feature trades a small static lookup table for a meaningful decode speedup, and a zero-allocation decode_into variant is available for performance-sensitive callers.

What You Get

  • Two core functions, encode and decode, translating between RGBA pixel buffers and short Blurhash strings
  • Optional image crate integration (encode_image/decode_image) for direct RgbaImage support
  • Optional gdk-pixbuf integration for GTK desktop applications
  • A zero-allocation decode_into variant for reusing an existing pixel buffer
  • A default-on fast-linear-to-srgb feature trading ~8KB of memory for roughly 60% faster decoding
  • A typed Error enum for validation failures instead of panics

Common Use Cases

  • Generating blurred image placeholders while a full-resolution image loads in a web or mobile UI
  • Precomputing and storing a compact Blurhash string alongside image metadata in a database or CDN
  • Building a Rust backend or CLI that mirrors the JS/Swift/Kotlin Blurhash reference implementations for cross-platform consistency
  • Server-side thumbnail and placeholder generation pipelines processing many images at once

Under The Hood

Architecture The crate is a flat, single-purpose library: src/lib.rs exposes the public encode/decode API and delegates to ac.rs (AC-component quantization), dc.rs (DC-component quantization), base83.rs (base83 string codec backed by a build-time-generated lookup table), util.rs (sRGB/linear color conversion), and error.rs (a typed Error enum). A build.rs script runs at compile time to generate perfect-hash lookup tables (the base83 character map, an sRGB lookup, and, behind the fast-linear-to-srgb feature, a fast linear-to-sRGB u8 lookup) that are pulled in via include!. Encode walks the pixel buffer computing weighted cosine basis-function coefficients per color channel and packs them into a base83 string; decode reverses through dc::decode/ac::decode and reconstructs pixels using the same basis functions, so the two paths are tightly symmetric and any change to the core math ripples through both.

Tech Stack A Rust 2018-edition crate published as blurhash on crates.io (repository name blurhash-rs). Optional Cargo features add integrations: image (RgbaImage encode/decode helpers via the image crate, versions >=0.23,<=0.25), gdk-pixbuf (GTK Pixbuf bindings), and the default-on fast-linear-to-srgb performance feature. Dev-dependencies bring in criterion for benchmarking (benches/encode.rs, benches/decode.rs) and proptest for property-based testing. Build-time codegen precomputes lookup tables rather than doing the work at runtime. CI runs on GitHub Actions (.github/workflows/build.yml). It’s a pure computation library with no async runtime and no external service calls.

Code Quality Inline unit tests cover encode/decode round-trips, base83 edge cases (including an overflow should_panic case), and non-ASCII rejection; proptest property tests fuzz component counts, arbitrary base83 strings, and full round-trips against a real fixture image, which is a notably rigorous choice for a crate this size. Errors are modeled as a typed Error enum (HashTooShort, LengthMismatch, InvalidAscii, InvalidBase83, ComponentsOutOfRange) implementing std::error::Error and Display, rather than panics or string errors, though a handful of internal assert!/assert_eq! invariant checks remain inside the hot decode loop. Naming is idiomatic Rust and no unsafe blocks are used. No committed rustfmt/clippy config means style enforcement isn’t verifiable from the repo alone.

API Design The public API is minimal and predictable: two free functions, encode/decode, taking raw RGBA byte slices plus width/height, with no builder types or config objects to construct. Feature-gated convenience wrappers (encode_image/decode_image, encode_pixbuf/decode_pixbuf) let callers skip manual byte-slice extraction when they already have a decoded image type, and decode_into offers a zero-allocation path for reused buffers. Doc comments carry runnable examples straight from the README. The design favors faithful, predictable compatibility with the reference Blurhash algorithm used by other-language implementations over introducing new capability.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search