npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

blur-score

v1.0.7

Published

Detect how blurry an image is (0-1 sharpness score) using Laplacian variance

Readme

blur-score

Module format

This package supports both ESM and CommonJS. CommonJS calls return the same Promises as the ESM API.

Detect how blurry an image is. Returns a sharpness score from 0 (very blurry) to 1 (very sharp) using the variance of Laplacian method.

Install

npm install blur-score

Requires Node.js >= 18. Uses sharp internally for image decoding.

Usage

import { getBlurScore, isBlurry } from 'blur-score';

// From a file path
const score = await getBlurScore('photo.jpg'); // e.g. 0.83

// From a Buffer
const score2 = await getBlurScore(fs.readFileSync('photo.jpg'));

// From a URL
const score3 = await getBlurScore('https://example.com/photo.jpg');

// Check against a threshold - true if score is below the threshold
const blurry = await isBlurry('photo.jpg', 0.5);

CommonJS is also supported via dynamic import:

const { getBlurScore, isBlurry } = await import('blur-score');

API

getBlurScore(input, options?)

Returns Promise<number> - a sharpness score between 0 and 1.

  • input: a file path (string), an http(s) URL (string), or image bytes (Buffer / Uint8Array).
  • options.calibration (default 60): the Laplacian variance value that maps to a score of 0.5. Raise it if sharp images score too high for your dataset; lower it if blurry images score too high.

isBlurry(input, threshold?, options?)

Returns Promise<boolean> - true when the image's sharpness score is below threshold.

  • threshold (default 0.5): the cutoff sharpness score.
  • options: same as getBlurScore.

How it works

  1. The image is converted to greyscale.
  2. A Laplacian kernel is convolved over the pixels to highlight edges.
  3. The variance of the Laplacian response is computed - sharp images with lots of edges produce high variance, blurry images produce low variance.
  4. The variance is mapped to a 0-1 score via variance / (variance + calibration).

Because the raw variance is unbounded and depends heavily on image content (not just blur), the calibration constant may need tuning for your specific use case.

Calibration notes

Real Laplacian variance is much lower than you might expect: a genuinely sharp handheld photo typically lands in the 20-100 range, while a UI screenshot with crisp text can hit 10,000+. The default calibration: 60 is tuned against real photos (not screenshots) so that:

  • Sharp, in-focus photos score roughly 0.5-0.7
  • Mild, barely-visible blur drops that to ~0.2-0.3
  • Clearly blurred images drop below 0.1

Known limitation: this method measures edge/high-frequency content, not "blur" directly. A photo with genuinely low detail - a soft-focus shot, a shallow depth-of-field background, a smooth studio backdrop - can score similarly low even when perfectly sharp, because there just isn't much high-frequency content to measure. If your images are visually distinctive in this way (product shots on plain backgrounds, portraits, macro photography), test against a representative sample and adjust calibration or your threshold accordingly rather than trusting the default blindly.

License

MIT

Limitations

Sharpness scores are heuristic and can vary with image size, noise, compression, and texture. They are not a camera-focus measurement.