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

@vojtechportes/minify-png

v0.1.2

Published

Node.js PNG minification library with edge-aware flat-region optimization and photo-safe palette recompression.

Readme

minify-png

npm version codecov

minify-png is a Node.js library for reducing PNG size with a combination of:

  • edge-aware flat-region cleanup for screenshots, UI assets, icons, diagrams, and illustrations
  • photo-safe PNG recompression for natural images where aggressive flat-region posterization would look bad

Minification shwcase

What It Does

For flat graphics, the library:

  • decodes the PNG into RGBA pixels
  • detects and protects edges
  • finds flat interior tiles
  • rejects gradient-like regions
  • selectively remaps accepted non-edge regions

For photo-like images, the library becomes conservative:

  • it avoids destructive flat-region remapping
  • it still tries smaller PNG encodes
  • it picks the smallest candidate that stays within a visual-difference budget

This means the package is best understood as:

PNG minification with selective flat-region optimization plus adaptive recompression.

Install

npm install @vojtechportes/minify-png

sharp is used when available for decoding and encoding. pngjs is included as a fallback.

You can also opt into a system-installed pngquant binary for stronger PNG compression without bundling it into this package.

Usage

import { encodeOptimizedPng, minifyPng } from '@vojtechportes/minify-png';
import { readFile, writeFile } from 'node:fs/promises';

const sourceBuffer = await readFile('input.png');
const result = await minifyPng(sourceBuffer);
const outputBuffer = await encodeOptimizedPng(result);

await writeFile('output.png', outputBuffer);

With optional external pngquant:

const result = await minifyPng(sourceBuffer);
const outputBuffer = await encodeOptimizedPng(result, {
  pngquant: true,
  qualityMode: 'aggressive',
});

You can also set qualityMode on minifyPng() directly, and encodeOptimizedPng() will use that hint automatically unless you override it:

const result = await minifyPng(sourceBuffer, {
  qualityMode: 'aggressive',
});
const outputBuffer = await encodeOptimizedPng(result);

If pngquant is not installed or is not found on PATH, the library silently falls back to the built-in encoder path.

CLI

After install, you can also run the package as a CLI:

minify-png --input input.png --output output.png

With optional external pngquant:

minify-png \
  --input input.png \
  --output output.png \
  --pngquant \
  --pngquant-bin "C:\pngquant\pngquant.exe" \
  --quality-mode aggressive \
  --pngquant-quality 90-98 \
  --pngquant-speed 3

Available flags:

  • --input, -i
  • --output, -o
  • --pngquant
  • --pngquant-bin
  • --pngquant-quality
  • --pngquant-speed
  • --quality-mode
  • --verbose
  • --help, -h

API

minifyPng(input, options?)

Analyzes a PNG or raw image input and returns a rewritten RGBA result together with processing stats.

Supported input:

  • Buffer | Uint8Array containing a PNG
  • raw image input with data, width, height, and channels

Returns:

  • width, height, channels
  • rewritten data as Uint8ClampedArray
  • stats describing edge protection, accepted tiles, rewritten pixels, and whether posterization was skipped for a photo-like image

encodeOptimizedPng(input, options?)

Encodes a minifyPng() result or a raw image input back to PNG.

By default it tries multiple PNG encoding strategies and keeps the smallest acceptable candidate.

analyzeFlatRegions(input, options?)

Returns intermediate analysis data:

  • edgeMask
  • tileMask
  • regionMask
  • regions

This is mainly useful for debugging and tuning thresholds.

Behavior Notes

  • Best results are typically on UI screenshots, dashboards, icons, and illustrations.
  • Natural photographs can still shrink well, but they are handled more conservatively to avoid obvious color shifts and posterization.
  • The library is deterministic.
  • Internal processing uses normalized 8-bit RGBA.

Options

The main options include:

  • tileSize
  • edgeThresholdColor
  • edgeThresholdAlpha
  • edgeDilateRadius
  • flatnessMaxDistance
  • flatnessP95Distance
  • gradientRejectionEnabled
  • gradientMaxDirectionalDrift
  • minRegionArea
  • minRegionThickness
  • posterizeMode
  • posterizeBitsPerChannel
  • outputDebug

Encoder options include:

  • compressionLevel
  • adaptiveFiltering
  • palette
  • colors
  • quality
  • effort
  • pngquant
  • qualityMode

Optional pngquant

encodeOptimizedPng() supports an opt-in external pngquant path:

const outputBuffer = await encodeOptimizedPng(result, {
  pngquant: {
    binaryPath: 'pngquant',
    quality: [90, 98],
    speed: 3,
  },
  qualityMode: 'aggressive',
});

Notes:

  • pngquant is never bundled by this package.
  • pngquant / libimagequant are not MIT-licensed. They are GPL/commercial licensed, so this package only supports them as an optional external tool.
  • The binary must already be installed on the system or otherwise available via binaryPath.
  • If pngquant is unavailable or its output does not pass the same visual checks, the library keeps the built-in result instead.

qualityMode

encodeOptimizedPng() supports three visual-threshold modes, and minifyPng() can carry the same mode forward as an encode hint:

  • strict: current safest default
  • balanced: slightly looser acceptance
  • aggressive: more willing to accept smaller lossy candidates

Current Design

The current implementation combines two strategies:

  1. Selective flat-region optimization for graphics-like PNGs.
  2. Candidate-based PNG recompression for photo-like PNGs.

It does not try to be a full semantic image optimizer, and it is still intentionally more conservative than dedicated hosted optimizers for some photographic images.

Development

npm test
npm run typecheck
npm run build
npm run coverage

To run the local sample pipeline in the test/ folder:

npm run test:png

To enable optional external pngquant for the local test runner:

npm run test:png:pngquant

To pass a custom binary path:

npm run test:png -- --pngquant --pngquant-bin "C:\pngquant\pngquant.exe"

You can also pass explicit quality and speed:

npm run test:png -- --pngquant --pngquant-bin "C:\pngquant\pngquant.exe" --pngquant-quality 90-98 --pngquant-speed 3 --quality-mode aggressive

The test runner now loads a root .env file through dotenv, so if you prefer, you can still set defaults there:

USE_PNGQUANT=1
PNGQUANT_BIN=C:\pngquant\pngquant.exe

If you want to verify whether pngquant was actually used, run with --verbose:

npm run test:png -- --pngquant --pngquant-bin "C:\pngquant\pngquant.exe" --quality-mode aggressive --verbose

The output will tell you whether each pngquant candidate was unavailable, rejected by the visual checks, accepted, or ultimately selected.

Coverage is uploaded from GitHub Actions to Codecov. The workflow expects a CODECOV_TOKEN repository secret.

To try the CLI from the repository without publishing:

npm run build
node dist/minify-png.js --input test/test.png --output test/test.min.png