This comparison evaluates eight prominent npm packages used for image compression, resizing, and optimization across different environments. The selection covers build-time tools (Webpack, Gulp), server-side libraries (Node.js), client-side utilities (Browser), and API-driven services. Understanding the trade-offs between pure JavaScript solutions, native bindings, and external services is critical for selecting the right tool for performance, maintenance, and deployment constraints.
Handling images in web applications involves more than just uploading files. You need to compress them to save bandwidth, resize them for different screens, and convert them to modern formats like WebP or AVIF. The JavaScript ecosystem offers tools for every stage of this workflow: build-time, server-side, client-side, and via external APIs. Let's compare how these eight packages tackle the challenge of image optimization.
For static assets, the best time to optimize is during the build process. This ensures users always download optimized files without extra runtime cost.
image-webpack-loader integrates directly into Webpack.
webpack.config.js, and it handles the rest.// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|jpeg|gif|svg)$/i,
use: [
{
loader: 'image-webpack-loader',
options: {
mozjpeg: { progressive: true, quality: 65 },
pngquant: { quality: [0.65, 0.90], speed: 4 }
}
}
]
}
]
}
};
gulp-imagemin is designed for Gulp pipelines.
// gulpfile.js
const gulp = require('gulp');
const imagemin = require('gulp-imagemin');
gulp.task('compress', () => {
return gulp.src('src/images/*')
.pipe(imagemin())
.pipe(gulp.dest('dist/images'));
});
compress-images acts as a CLI utility.
# Command Line Usage
npx compress-images ./src/images/ ./dist/images/ --compressor imageMin
When images are uploaded by users or generated dynamically, you need server-side tools. The choice here usually comes down to performance versus compatibility.
sharp is the performance leader.
// server.js
const sharp = require('sharp');
await sharp('input.jpg')
.resize(800, 600)
.webp({ quality: 80 })
.toFile('output.webp');
jimp is the compatibility leader.
// server.js
const Jimp = require('jimp');
async function processImage() {
const image = await Jimp.read('input.jpg');
await image.resize(800, Jimp.AUTO).quality(80).write('output.jpg');
}
imagemin focuses on minification rather than manipulation.
imagemin-mozjpeg or imagemin-pngquant.// server.js
const imagemin = require('imagemin');
const imageminMozjpeg = require('imagemin-mozjpeg');
(async () => {
const files = await imagemin(['images/*.{jpg,png}'], {
destination: 'build/images',
plugins: [imageminMozjpeg({ quality: 75 })]
});
console.log(files);
})();
Sometimes you need to process images before they even leave the user's device. This saves upload time and server resources.
compressorjs runs entirely in the browser.
// client.js
import Compressor from 'compressorjs';
new Compressor(file, {
quality: 0.6,
success(result) {
// result is a compressed Blob
uploadToServer(result);
},
error(err) {
console.log(err.message);
},
});
If you don't want to manage libraries or server CPU, you can use an external service.
tinify sends images to the Tinify API.
// server.js
const tinify = require('tinify');
tinify.key = "YOUR_API_KEY";
const source = tinify.fromFile("input.jpg");
await source.toFile("output.jpg");
The biggest technical divide in this list is between native bindings and pure JavaScript.
sharp is significantly faster than jimp because it leverages compiled code. For high-traffic sites processing thousands of images, sharp reduces CPU load and latency.jimp is easier to deploy in restricted environments (like some serverless functions or Docker containers without build tools) because it doesn't need node-gyp.// sharp: Fast, native
// Processing time: ~50ms for a 4K image resize
await sharp('large.jpg').resize(100, 100).toBuffer();
// jimp: Slower, pure JS
// Processing time: ~500ms+ for the same task
const img = await Jimp.read('large.jpg');
await img.resize(100, Jimp.AUTO).getBufferAsync(Jimp.MIME_JPEG);
Integration effort varies based on where the tool fits in your architecture.
image-webpack-loader, gulp-imagemin): Zero runtime code. You configure them once, and they work silently in the background. However, they cannot handle dynamic user uploads.sharp, jimp, tinify): Require code in your API routes or server logic. You must handle streams, buffers, and error states manually.compressorjs): Require logic in your frontend components. You must handle browser compatibility and fallbacks.Some tools in this list are wrappers around older technologies.
imagemin plugins are powerful but can suffer from dependency hell. Many plugins are unmaintained. sharp is generally more actively maintained for modern formats like AVIF.gulp-imagemin ties you to the Gulp ecosystem, which has seen less adoption in favor of npm scripts or bundlers in modern frontend architecture.tinify is stable but introduces a dependency on an external service. If the API goes down or changes pricing, your build or upload flow breaks.| Package | Environment | Primary Use Case | Native Deps? | API Key? |
|---|---|---|---|---|
compress-images | CLI / Node | Batch folder compression | No | No |
compressorjs | Browser | Pre-upload compression | No | No |
gulp-imagemin | Build (Gulp) | Gulp pipeline optimization | Yes (via plugins) | No |
image-webpack-loader | Build (Webpack) | Webpack bundle optimization | Yes (via plugins) | No |
imagemin | Node / CLI | Minification engine | Yes (via plugins) | No |
jimp | Node / Browser | Pure JS manipulation | No | No |
sharp | Node | High-perf manipulation | Yes (libvips) | No |
tinify | Node / API | Max compression via SaaS | No | Yes |
sharp is the default recommendation for server-side Node.js applications due to its speed and modern format support.
image-webpack-loader is the standard for static assets in Webpack projects.
compressorjs is the go-to for client-side resizing before upload.
jimp remains a valid choice only when native modules are strictly forbidden.
tinify is a premium option for teams that prefer managing API keys over managing image libraries.
Final Thought: Image optimization is not one-size-fits-all. A robust architecture often combines these tools: use image-webpack-loader for static assets, sharp for dynamic user uploads, and compressorjs to reduce upload payload size on the client.
Choose compress-images if you need a simple CLI tool to batch compress images in a folder structure without writing custom scripts. It is best suited for one-off tasks or simple CI/CD steps where a full build pipeline is overkill. However, verify its maintenance status as CLI wrappers can become outdated compared to core libraries.
Choose compressorjs when image processing must happen directly in the browser before upload. This is ideal for reducing bandwidth costs and improving user experience by shrinking files on the client side. It relies on browser APIs, so it cannot perform server-side batch processing.
Choose gulp-imagemin if your build pipeline is already heavily invested in Gulp. It integrates seamlessly into Gulp streams but adds a dependency on the Gulp ecosystem. For new projects, modern bundlers like Webpack or Vite are generally preferred over Gulp.
Choose image-webpack-loader if you are using Webpack and want images optimized automatically during the build process. It wraps imagemin and requires no extra code in your application logic. It is not suitable for runtime image manipulation or non-Webpack projects.
Choose imagemin if you need a flexible, minification-focused library that supports various plugins for different formats (PNG, JPEG, GIF, SVG). It is the core engine behind many other tools. Use it when you want to build a custom optimization script without the overhead of a full image manipulation library.
Choose jimp if you require a pure JavaScript solution that does not require native compilation or external dependencies. It is excellent for cross-platform compatibility (including serverless environments where native binaries are restricted) but is significantly slower than native alternatives for large batches.
Choose sharp for high-performance server-side image processing in Node.js. It uses libvips for speed and efficiency, making it the industry standard for resizing and format conversion on the backend. Avoid it if you cannot install native dependencies or need to run in a pure JavaScript environment.
Choose tinify if you prioritize maximum compression ratios and are willing to use a paid API service. It offloads processing to Tinify's servers, ensuring consistent quality without managing local libraries. It is not suitable for offline processing or high-volume free tiers due to API limits.
compress-images Minify size your images. Image compression with extension: jpg/jpeg, svg, png, gif.
Minify size your images. Image compression with extension: jpg/jpeg, svg, png, gif.

You can also use:
You can use different algorithms and methods for compressing images with many options.
jpegtran, mozjpeg, webp, guetzli, jpegRecompress, jpegoptim, tinify;pngquant, optipng, pngout, webp, pngcrush, tinify;svgo;gifsicle, giflossy, gif2webp;You can even minify images by using a combination of compression algorithms. As an example -
mozjpeg+jpegoptimorjpegtran+mozjpegor any other algorithm.
If you get an error, the error log will be saved. Default path
./log/compress-images.
If you get an error, alternative algorithms for compressing images can be used. As an example: you want to compress images in
jpegRecompress, but you get the error Unsupported color conversion request, so an alternative algorithm to compress the images can be used, likemozjpeg.
You can specify the path to source images folder and all images in the folder will be compressed and moved to output folder.
As an example, one of many:
INPUT ['src/img/source/**/*.{jpg,JPG,jpeg,JPEG,gif,png,svg}']
OUTPUT ['build/img/']
You should have in your path slash: /.
If you have slash \ it may be to replaced: input.replace(/\\/g, '/');

Other useful plugins:
npm install compress-images --save-dev
https://github.com/semiromid/compress-images/tree/master/example
const compress_images = require("compress-images"),
INPUT_path_to_your_images,
OUTPUT_path;
INPUT_path_to_your_images = "src/img/**/*.{jpg,JPG,jpeg,JPEG,png,svg,gif}";
OUTPUT_path = "build/img/";
compress_images(INPUT_path_to_your_images, OUTPUT_path, { compress_force: false, statistic: true, autoupdate: true }, false,
{ jpg: { engine: "mozjpeg", command: ["-quality", "60"] } },
{ png: { engine: "pngquant", command: ["--quality=20-50", "-o"] } },
{ svg: { engine: "svgo", command: "--multipass" } },
{ gif: { engine: "gifsicle", command: ["--colors", "64", "--use-col=web"] } },
function (error, completed, statistic) {
console.log("-------------");
console.log(error);
console.log(completed);
console.log(statistic);
console.log("-------------");
}
);
const compress_images = require("compress-images");
function MyFun() {
compress_images(
"src/img/**/*.{jpg,JPG,jpeg,JPEG,png,svg,gif}",
"build/img/",
{ compress_force: false, statistic: true, autoupdate: true },
false,
{ jpg: { engine: "mozjpeg", command: ["-quality", "60"] } },
{ png: { engine: "pngquant", command: ["--quality=20-50", "-o"] } },
{ svg: { engine: "svgo", command: "--multipass" } },
{
gif: { engine: "gifsicle", command: ["--colors", "64", "--use-col=web"] },
},
function (err, completed) {
if (completed === true) {
// Doing something.
}
}
);
}
const compress_images = require('compress-images');
// We will be compressing images [jpg] with two algorithms, [webp] and [jpg];
//[jpg] ---to---> [webp]
compress_images(
"src/img/**/*.{jpg,JPG,jpeg,JPEG}",
"build/img/",
{ compress_force: false, statistic: true, autoupdate: true },
false,
{ jpg: { engine: "webp", command: false } },
{ png: { engine: false, command: false } },
{ svg: { engine: false, command: false } },
{ gif: { engine: false, command: false } },
function (err) {
if (err === null) {
//[jpg] ---to---> [jpg(jpegtran)] WARNING!!! autoupdate - recommended to turn this off, it's not needed here - autoupdate: false
compress_images(
"src/img/**/*.{jpg,JPG,jpeg,JPEG}",
"build/img/",
{ compress_force: false, statistic: true, autoupdate: false },
false,
{ jpg: { engine: "jpegtran", command: false } },
{ png: { engine: false, command: false } },
{ svg: { engine: false, command: false } },
{ gif: { engine: false, command: false } },
function () {}
);
} else {
console.error(err);
}
}
);
const compress_images = require('compress-images');
// Combine compressing images [jpg] with two different algorithms, [jpegtran] and [mozjpeg];
//[jpg] ---to---> [jpg(jpegtran)]
compress_images(
"src/img/source/**/*.{jpg,JPG,jpeg,JPEG}",
"src/img/combination/",
{ compress_force: false, statistic: true, autoupdate: true },
false,
{
jpg: {
engine: "jpegtran",
command: ["-trim", "-progressive", "-copy", "none", "-optimize"],
},
},
{ png: { engine: false, command: false } },
{ svg: { engine: false, command: false } },
{ gif: { engine: false, command: false } },
function () {
//[jpg(jpegtran)] ---to---> [jpg(mozjpeg)] WARNING!!! autoupdate - recommended to turn this off, it's not needed here - autoupdate: false
//----------------
compress_images(
"src/img/combination/**/*.{jpg,JPG,jpeg,JPEG}",
"build/img/",
{ compress_force: false, statistic: true, autoupdate: false },
false,
{ jpg: { engine: "mozjpeg", command: ["-quality", "75"] } },
{ png: { engine: false, command: false } },
{ svg: { engine: false, command: false } },
{ gif: { engine: false, command: false } },
function () {}
);
//----------------
}
);
const compress_images = require('compress-images');
//[jpg+gif+png+svg] ---to---> [jpg(webp)+gif(gifsicle)+png(webp)+svg(svgo)]
compress_images('src/img/source/**/*.{jpg,JPG,jpeg,JPEG,gif,png,svg}', 'build/img/', {compress_force: false, statistic: true, autoupdate: true}, false,
{jpg: {engine: 'webp', command: false}},
{png: {engine: 'webp', command: false}},
{svg: {engine: 'svgo', command: false}},
{gif: {engine: 'gifsicle', command: ['--colors', '64', '--use-col=web']}}, function(){
//-------------------------------------------------
//[jpg] ---to---> [jpg(jpegtran)] WARNING!!! autoupdate - recommended to turn this off, it's not needed here - autoupdate: false
compress_images('src/img/source/**/*.{jpg,JPG,jpeg,JPEG}', 'src/img/combine/', {compress_force: false, statistic: true, autoupdate: false}, false,
{jpg: {engine: 'jpegtran', command: ['-trim', '-progressive', '-copy', 'none', '-optimize']}},
{png: {engine: false, command: false}},
{svg: {engine: false, command: false}},
{gif: {engine: false, command: false}}, function(){
//[jpg(jpegtran)] ---to---> [jpg(mozjpeg)] WARNING!!! autoupdate - recommended to turn this off, it's not needed here - autoupdate: false
compress_images('src/img/combine/**/*.{jpg,JPG,jpeg,JPEG}', 'build/img/', {compress_force: false, statistic: true, autoupdate: false}, false,
{jpg: {engine: 'mozjpeg', command: ['-quality', '75']}},
{png: {engine: false, command: false}},
{svg: {engine: false, command: false}},
{gif: {engine: false, command: false}}, function(){
//[png] ---to---> [png(pngquant)] WARNING!!! autoupdate - recommended to turn this off, it's not needed here - autoupdate: false
compress_images('src/img/source/**/*.png', 'build/img/', {compress_force: false, statistic: true, autoupdate: false}, false,
{jpg: {engine: false, command: false}},
{png: {engine: 'pngquant', command: ['--quality=30-60', '-o']}},
{svg: {engine: false, command: false}},
{gif: {engine: false, command: false}}, function(){
});
});
});
//-------------------------------------------------
});
Sometimes you could get errors, and then use alternative configuration "compress-images". As an example, one of many:
If you get an error from 'jpegRecompress', for example, the error "Unsupported color conversion request". In this case, an alternative image compression algorithm will be used.
An error log will be created at path './log/lib/compress-images'.
The algorithm 'mozjpeg' will attempt to be used instead.
const
compress_images = require('compress-images'),
INPUT_path_to_your_images = 'src/**/*.{jpg,JPG,jpeg,JPEG,png,svg,gif}',
OUTPUT_path = 'build/';
compress_images(INPUT_path_to_your_images, OUTPUT_path, {compress_force: false, statistic: true, autoupdate: true, pathLog: './log/lib/compress-images'}, false,
{jpg: {engine: 'jpegRecompress', command: ['--quality', 'high', '--min', '60']}},
{png: {engine: 'pngquant', command: ['--quality=20-50', '-o']}},
{svg: {engine: 'svgo', command: '--multipass'}},
{gif: {engine: 'gifsicle', command: ['--colors', '64', '--use-col=web']}}, function(err, completed){
if(err !== null){
//---------------------------------------
//if you get an ERROR from 'jpegRecompress' ---> We can use alternate config of compression
//---------------------------------------
if(err.engine === 'jpegRecompress'){
compress_images(err.input, err.output, {compress_force: false, statistic: true, autoupdate: true}, false,
{jpg: {engine: 'mozjpeg', command: ['-quality', '60']}},
{png: {engine: false, command: false}},
{svg: {engine: false, command: false}},
{gif: {engine: false, command: false}}, function(err){
if(err !== null){
//Alternative config of compression
}
});
}
//---------------------------------------
}
});
Compressing an image in the same folder (currently this only works with 'pngquant')
const
compress_images = require('compress-images'),
fs = require('fs'),
INPUT_path_to_your_images = 'src/img/**/!(*-min).png',
OUTPUT_path = 'src/img/';
compress_images(INPUT_path_to_your_images, OUTPUT_path, {compress_force: true, statistic: false, autoupdate: true}, false,
{jpg: {engine: false, command: false}},
{png: {engine: 'pngquant', command: ['--quality=20-50', '--ext=-min.png', '--force']}},
{svg: {engine: false, command: false}},
{gif: {engine: false, command: false}}, function(err, completed, statistic){
if(err === null){
fs.unlink(statistic.input, (err) => {
if (err) throw err;
console.log('successfully compressed and deleted '+statistic.input);
});
}
});
<picture>
<source type="image/webp" srcset="//hostname/build/img/art/1/chat.webp">
<img width="700" height="922" alt="test" src="https://raw.githubusercontent.com/Yuriy-Svetlov/compress-images/HEAD///hostname/build/img/art/1/chat.jpg">
</picture>
compress_images(input, output, option, globoption, enginejpg, enginepng, enginesvg, enginegif, callback)
input (type:string): Path to source image or images;
Example:
1. 'src/img/**/*.{jpg,JPG,jpeg,JPEG,png,svg,gif}';
2. 'src/img/**/*.jpg';
3. 'src/img/*.jpg';
4. 'src/img/myimagename.jpg';
output (type:string): Path to compress images;
Example:
1. 'build/img/';
option (type:plainObject): Options module`s «compress-images»;
true or false;true or false;./log/compress-images;true or false; {compress_force: false, statistic: true, autoupdate: true};globoption (type:boolean|other): Options module`s glob. Also you can set false;
enginejpg (type:plainObject): Engine for compressing jpeg and options compress. Key to be jpg;
jpegtran,mozjpeg, webp, guetzli, jpegRecompress, jpegoptim, tinify;false or commands array.
For jpegtran - ['-trim', '-progressive', '-copy', 'none', '-optimize'] in details; jpegtran;
For mozjpeg - ['-quality', '10'] in details mozjpeg;
For webp - ['-q', '60'] in details webp;
For guetzli - ['--quality', '84'] (Very long compresses on Win 8.1 https://github.com/google/guetzli/issues/238) in details guetzli;
To use guetzli you must npm install guetzli --save, this library does not work properly on some OS and platforms.
For jpegRecompress - ['--quality', 'high', '--min', '60'] in details jpegRecompress;
For jpegoptim - ['--all-progressive', '-d']
To use jpegoptim you must npm install jpegoptim-bin --save, this library does not work properly on some OS and platforms.
from https://github.com/imagemin/jpegoptim-bin
Issues!
May be a problems with installation and use on Win 7 x32 and maybe other OS:
compress-images - issues/21
Caution! if do not specify '-d' all images will be compressed in the source folder and will be replaced.
For Windows x32 and x63 also, you can use https://github.com/vikas5914/jpegoptim-win. Copy jpegoptim-32.exe and replace and rename in "node_modules\jpegoptim-bin\vendor\jpegoptim.exe"
For tinify - ['copyright', 'creation', 'location'] In details tinify;
{jpg: {engine: 'mozjpeg', command: ['-quality', '60']}; {jpg: {engine: 'tinify', key: "sefdfdcv335fxgfe3qw", command: ['copyright', 'creation', 'location']}}; {jpg: {engine: 'tinify', key: "sefdfdcv335fxgfe3qw", command: false}};enginepng (type:plainObject): Engine for compressing png and options for compression. Key to be png;
pngquant,optipng, pngout, webp, pngcrush, tinify;false or commands array.
['--quality=20-50', '-o'] If you want to compress in the same folder, as example: ['--quality=20-50', '--ext=.png', '--force']. To use this library you need to install it manually. It does not work properly on some OS (Win 7 x32 and maybe other). npm install pngquant-bin --save
Quality should be in format min-max where min and max are numbers in range 0-100. Can be problems with cyrillic filename issues/317
In details:
pngquant and
pngquant-bin - wrappernpm install --save optipng-bin in details optipng-bin - wrapper
and optipng;['-q', '60'] in details webp;['-reduce', '-brute'] in details pngcrush;['copyright', 'creation', 'location'] in details tinify;{png: {engine: 'webp', command: ['-q', '100']}; {png: {engine: 'tinify', key: "sefdfdcv335fxgfe3qw", command: ['copyright', 'creation', 'location']}}; {png: {engine: 'optipng', command: false}};enginesvg (type:plainObject): Engine for compressing svg and options for compression. Key to be svg;
svgo;false or commands type string.
'--multipass' in details svgo; {svg: {engine: 'svgo', command: '--multipass'}; {svg: {engine: 'svgo', command: false}};enginegif (type:plainObject): Engine for compressing gif and options for compression. Key to be gif;
gifsicle, giflossy, gif2webp;false or commands type array.
npm install gifsicle --save.
Example options:['--colors', '64', '--use-col=web'] or ['--optimize'] In details gifsicle;['--lossy=80'] In details giflossy;['-f', '80', '-mixed', '-q', '30', '-m', '2'] in details gif2webp; {gif: {engine: 'gifsicle', command: ['--colors', '64', '--use-col=web', '--scale', ' 0.8']}}; {gif: {engine: 'giflossy', command: false}}; {gif: {engine: 'gif2webp', command: ['-f', '80', '-mixed', '-q', '30', '-m', '2']}};callback (err, completed, statistic): returns:
true - result completed.false - result not completed.inputpath_out_newalgorithmsize_insize_outputpercenterr
const { compress } = require('compress-images/promise');
const INPUT_path_to_your_images = 'src/img/**/*.{jpg,JPG,jpeg,JPEG,png}';
const OUTPUT_path = 'build/img/';
const processImages = async () => {
const result = await compress({
source: INPUT_path_to_your_images,
destination: OUTPUT_path,
enginesSetup: {
jpg: { engine: 'mozjpeg', command: ['-quality', '60']},
png: { engine: 'pngquant', command: ['--quality=20-50', '-o']},
}
});
const { statistics, errors } = result;
// statistics - all processed images list
// errors - all errros happened list
};
processImages();
Using onProgress
const { compress } = require('compress-images/promise');
const INPUT_path_to_your_images = 'src/img/**/*.{jpg,JPG,jpeg,JPEG,png}';
const OUTPUT_path = 'build/img/';
const processImages = async (onProgress) => {
const result = await compress({
source: INPUT_path_to_your_images,
destination: OUTPUT_path,
onProgress,
enginesSetup: {
jpg: { engine: 'mozjpeg', command: ['-quality', '60']},
png: { engine: 'pngquant', command: ['--quality=20-50', '-o']},
}
});
const { statistics, errors } = result;
// statistics - all processed images list
// errors - all errros happened list
};
processImages((error, statistic, completed) => {
if (error) {
console.log('Error happen while processing file');
console.log(error);
return;
}
console.log('Sucefully processed file');
console.log(statistic)
});
promise/compress(params)
params (type:plainObject): Module options;
{ jpg: <enginejpg>, png: <enginepng> }, see details above;returns Promise with object:
If this is a useful thing for you, support the project.
PayPal | https://www.paypal.com/myaccount/transfer/send startpascal1@mail.ru
Visa Card | 4731 1856 1426 6432 First name and Last name: SEMINA TAMARA or SEMINA TAMARA PETROVNA
Payeer | payeer.com No.[P77135727]
PaYoneer | https://www.payoneer.com startpascal1@mail.ru
gif2webp https://developers.google.com/speed/webp/docs/gif2webp author is Google;
Node package giflossy https://www.npmjs.com/package/giflossy Author is Jihchi;
gifsicle and giflossy http://www.lcdf.org/gifsicle/ author is Eddie Kohler;
gifsicle-bin https://github.com/imagemin/gifsicle-bin author is Kevva;
svgo https://www.npmjs.com/package/svgo author is Greli;
pngcrush https://pmt.sourceforge.io/pngcrush/ author is Glenn Randers-Pehrson;
pngcrush-bin https://github.com/imagemin/pngcrush-bin author is Kevva;
webp https://developers.google.com/speed/webp/ author is Google;
pngout http://advsys.net/ken/util/pngout.htm author is Kerry Watson, with updates by Ken Silverman and Matthew Fearnley;
pngout-bin https://github.com/imagemin/pngout-bin author is 1000ch;
pngquant https://pngquant.org/ author is Kornel Lesiński and contributors. It's based on code by Greg Roelofs and Jef Poskanzer;
pngquant-bin https://github.com/imagemin/pngquant-bin author is Kevva;
tinypng https://tinypng.com/developers/reference/nodejs author is Voormedia;
tinyjpg https://tinyjpg.com/ author is Voormedia;
jpegoptim https://github.com/tjko/jpegoptim author is Tjko;
jpegoptim-bin https://github.com/imagemin/jpegoptim-bin author is 1000ch;
jpeg-archive https://github.com/danielgtaylor/jpeg-archive author is Danielgtaylor;
jpeg-recompress-bin https://github.com/imagemin/jpeg-recompress-bin author is 1000ch;
guetzli https://github.com/google/guetzli author is Google;
guetzli-bin https://github.com/imagemin/guetzli-bin author is 1000ch;
mozjpeg-bin https://github.com/imagemin/mozjpeg-bin author is 1000ch;
mozjpeg https://github.com/mozilla/mozjpeg author is Pornel;
jpegtran-bin https://github.com/imagemin/jpegtran-bin author is 1000ch;
libjpeg-turbo https://libjpeg-turbo.org/ author is Dcommander;
Vectors https://www.flaticon.com/authors/vectors-market author is Vectors Market;
colors https://www.npmjs.com/package/colors author is Marak;
glob https://www.npmjs.com/package/glob author is Isaacs;
mkdirp https://www.npmjs.com/package/mkdirp author is Substack;
bytes https://www.npmjs.com/package/bytes author is Dougwilson;
Разработка сайтов Веб-студия Харьков
SEMINA TAMARA
MIT License
Copyright (c) 2017 TAMARA SEMINA
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.