Optimize Images with 'imagemin': A Complete Developer's Guide
In modern web development, performance is paramount. Among many factors that impact load speed, image size is often one of the biggest culprits—especially when dealing with high-resolution assets in formats like .png, .jpg, or .svg. Manually optimizing each image can be time-consuming and inefficient, especially at scale.
This is where imagemin becomes an essential tool for developers.
In this article, we’ll walk through how to use imagemin to automatically compress and optimize images of all types in your project—without compromising visual quality.
Why Image Optimization Matters
- Faster load times: Smaller images lead to quicker page rendering, improving UX and SEO.
- Reduced bandwidth usage: Especially important for users on mobile or slow networks.
- Better Lighthouse scores: Google ranks sites better when performance metrics are optimized.
Meet 'imagemin'
imagemin is a powerful image compression tool built for Node.js. It supports a wide range of image formats and plugins, making it easy to integrate into any project—whether you're working with a static site, a React/Vite app, or even a browser extension.
Key Features
- Supports PNG, JPEG, SVG, and GIF
- Lossy and lossless compression options
- Plugin-based and extendable
- Works from CLI or Node scripts
- Easily integrated into build pipelines
Installation
First, install imagemin and the necessary plugins for the formats you want to compress:
1npm install imagemin imagemin-mozjpeg imagemin-pngquant imagemin-svgo --save-devPlugin Breakdown
imagemin-mozjpeg: For compressing JPEG files (lossy)imagemin-pngquant: For compressing PNG files (lossy)imagemin-svgo: For optimizing SVG files
Project Structure Example
Let’s assume you have this folder structure:
1/images
2 /original
3 - logo.png
4 - banner.jpg
5 - icon.svg
6 /optimizedWe’ll write a script that compresses all images from /images/original and saves the optimized versions in /images/optimized.
Sample Node.js Script
Create a script file compress-images.js:
1// compress-images.js
2
3import imagemin from 'imagemin';
4import imageminMozjpeg from 'imagemin-mozjpeg';
5import imageminPngquant from 'imagemin-pngquant';
6import imageminSvgo from 'imagemin-svgo';
7import path from 'path';
8
9const inputPath = path.resolve('images/original/*.{jpg,jpeg,png,svg}');
10const outputPath = path.resolve('images/optimized');
11
12(async () => {
13 try {
14 const files = await imagemin([inputPath], {
15 destination: outputPath,
16 plugins: [
17 imageminMozjpeg({ quality: 75 }),
18 imageminPngquant({ quality: [0.6, 0.8] }),
19 imageminSvgo({
20 plugins: [{
21 name: 'removeViewBox',
22 active: false
23 }]
24 })
25 ]
26 });
27
28 console.log(`Optimized ${files.length} images successfully.`);
29 } catch (err) {
30 console.error('Image optimization failed:', err);
31 }
32})();Run the script:
1node compress-images.jsAutomate with NPM Script
Add this to your package.json:
1{
2 "scripts": {
3 "optimize-images": "node compress-images.js"
4 }
5}Now simply run:
1npm run optimize-imagesExample Results
| Image Type | Original Size | Optimized Size | Savings |
|---|---|---|---|
| banner.jpg | 980 KB | 320 KB | 67% |
| logo.png | 450 KB | 150 KB | 66% |
| icon.svg | 120 KB | 80 KB | 33% |
⚠️ Tip: Always test optimized images visually to ensure acceptable quality levels, especially for lossy compression.
Bonus: Watch & Optimize Automatically
Want to automate this in development? Use chokidar to watch for changes and auto-run optimization:
Install chokidar:
1npm install chokidar --save-devExample script:
1// watch-images.js
2import chokidar from 'chokidar';
3import { exec } from 'child_process';
4
5console.log('Watching for image changes in images/original...');
6
7chokidar
8 .watch('images/original/**/*.{jpg,jpeg,png,svg}')
9 .on('add', (filePath) => {
10 console.log(`New image detected: ${filePath}`);
11 exec('npm run optimize-images');
12 })
13 .on('change', (filePath) => {
14 console.log(`Re-optimizing ${filePath}...`);
15 exec('npm run optimize-images');
16 });Also add this script to your package.json:
1{
2 "scripts": {
3 "watch:images": "node watch-images.js"
4 }
5}Now simply run:
1npm run watch:imagesIntegrations
- Webpack: Use
image-webpack-loader - Vite: Use
vite-imagetoolsor pre-build withimagemin - Gulp: Use the
gulp-imageminplugin - CI/CD: Add the script before deployment in your pipeline
Conclusion
If you're working on performance optimization, image compression should be a top priority. With imagemin, you gain full control over how images are compressed and delivered—without relying on third-party tools or online services.
Compress once. Deliver fast. Improve UX.