Build Tool Image Plugins Compared
Compare image optimization plugins for Webpack, Vite, Rollup, and other build tools. Configuration examples, performance tips, and recommendations.
Modern build tools can automatically optimize images during the build process. This guide compares plugins across major bundlers and provides configuration examples.
Quick Comparison
| Build Tool | Primary Plugin | Modern Formats | Responsive |
|---|---|---|---|
| Webpack | image-minimizer-webpack-plugin | Yes | With loader |
| Vite | vite-plugin-image-optimizer | Yes | Limited |
| Rollup | @rollup/plugin-image | Basic | No |
| Parcel | Built-in | Yes | No |
| esbuild | Manual | Yes | No |
Webpack Plugins
image-minimizer-webpack-plugin
The most comprehensive Webpack image optimization solution.
Installation
npm install image-minimizer-webpack-plugin sharp imagemin --save-dev
# Or with specific optimizers
npm install imagemin-mozjpeg imagemin-pngquant imagemin-svgo --save-dev
Basic Configuration
// webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
optimization: {
minimizer: [
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.sharpMinify,
options: {
encodeOptions: {
jpeg: { quality: 80 },
webp: { quality: 80 },
avif: { quality: 65 },
png: { compressionLevel: 9 }
}
}
}
})
]
}
};
With Format Conversion
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
module.exports = {
optimization: {
minimizer: [
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.sharpMinify,
options: {
encodeOptions: {
jpeg: { quality: 80 }
}
}
},
generator: [
{
preset: 'webp',
implementation: ImageMinimizerPlugin.sharpGenerate,
options: {
encodeOptions: {
webp: { quality: 80 }
}
}
},
{
preset: 'avif',
implementation: ImageMinimizerPlugin.sharpGenerate,
options: {
encodeOptions: {
avif: { quality: 65 }
}
}
}
]
})
]
}
};
Usage in Code
// Import with query for specific format
import heroWebP from './hero.jpg?as=webp';
import heroAvif from './hero.jpg?as=avif';
// In JSX
<picture>
<source srcSet={heroAvif} type="image/avif" />
<source srcSet={heroWebP} type="image/webp" />
<img src={hero} alt="Hero" />
</picture>
responsive-loader
Generates multiple sizes for responsive images.
Installation
npm install responsive-loader sharp --save-dev
Configuration
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpe?g)$/i,
use: {
loader: 'responsive-loader',
options: {
adapter: require('responsive-loader/sharp'),
sizes: [320, 640, 960, 1280, 1920],
placeholder: true,
placeholderSize: 20,
format: 'webp',
quality: 80
}
}
}
]
}
};
Usage
import heroImages from './hero.jpg?sizes[]=320&sizes[]=640&sizes[]=960';
// Returns object with srcSet, src, placeholder, etc.
<img
src={heroImages.src}
srcSet={heroImages.srcSet}
sizes="(max-width: 960px) 100vw, 960px"
alt="Hero"
/>
imagemin-webpack-plugin (Legacy)
Older but still widely used.
const ImageminPlugin = require('imagemin-webpack-plugin').default;
const imageminMozjpeg = require('imagemin-mozjpeg');
const imageminPngquant = require('imagemin-pngquant');
module.exports = {
plugins: [
new ImageminPlugin({
test: /\.(jpe?g|png|gif|svg)$/i,
plugins: [
imageminMozjpeg({ quality: 80 }),
imageminPngquant({ quality: [0.65, 0.9] })
]
})
]
};
Vite Plugins
vite-plugin-image-optimizer
Comprehensive image optimization for Vite.
Installation
npm install vite-plugin-image-optimizer sharp svgo --save-dev
Configuration
// vite.config.js
import { defineConfig } from 'vite';
import { ViteImageOptimizer } from 'vite-plugin-image-optimizer';
export default defineConfig({
plugins: [
ViteImageOptimizer({
jpeg: {
quality: 80
},
png: {
quality: 80
},
webp: {
quality: 80
},
avif: {
quality: 65
},
svg: {
plugins: [
{ name: 'removeViewBox', active: false },
{ name: 'removeDimensions', active: true }
]
}
})
]
});
vite-imagetools
Powerful image transformation with URL query parameters.
Installation
npm install vite-imagetools --save-dev
Configuration
// vite.config.js
import { defineConfig } from 'vite';
import { imagetools } from 'vite-imagetools';
export default defineConfig({
plugins: [
imagetools({
defaultDirectives: (url) => {
return new URLSearchParams({
format: 'webp',
quality: '80'
});
}
})
]
});
Usage
// Query-based transforms
import hero from './hero.jpg?w=800&h=600&format=webp';
import heroSrcSet from './hero.jpg?w=400;800;1200&format=webp&as=srcset';
import heroMeta from './hero.jpg?w=800&format=webp&as=meta';
// Picture element helper
import { getImage } from './hero.jpg?w=800&format=webp;avif&as=picture';
Directives Reference
| Directive | Example | Description |
|---|---|---|
| w | ?w=800 | Width |
| h | ?h=600 | Height |
| format | ?format=webp | Output format |
| quality | ?quality=80 | Compression quality |
| as | ?as=srcset | Output type |
| blur | ?blur=10 | Blur amount |
| tint | ?tint=#ff0000 | Tint color |
unplugin-imagemin
Universal plugin working with Vite, Webpack, Rollup.
// vite.config.js
import { defineConfig } from 'vite';
import imagemin from 'unplugin-imagemin/vite';
export default defineConfig({
plugins: [
imagemin({
conversion: [
{ from: 'jpeg', to: 'webp' },
{ from: 'png', to: 'webp' },
{ from: 'jpeg', to: 'avif' }
],
compress: {
jpg: { quality: 80 },
jpeg: { quality: 80 },
png: { quality: 80 },
webp: { quality: 80 },
avif: { quality: 65 }
}
})
]
});
Rollup Plugins
@rollup/plugin-image
Basic image handling for Rollup.
npm install @rollup/plugin-image --save-dev
// rollup.config.js
import image from '@rollup/plugin-image';
export default {
plugins: [
image({
include: ['**/*.png', '**/*.jpg', '**/*.svg'],
dom: false
})
]
};
rollup-plugin-imagemin
Image optimization for Rollup.
import imagemin from 'rollup-plugin-imagemin';
export default {
plugins: [
imagemin({
jpegtran: { progressive: true },
pngquant: { quality: [0.65, 0.9] },
gifsicle: { interlaced: true },
svgo: { plugins: [{ removeViewBox: false }] }
})
]
};
Parcel
Parcel has built-in image optimization.
Configuration
// package.json or .parcelrc
{
"@parcel/transformer-image": {
"quality": 80
}
}
Query Parameters
// In code
import hero from './hero.jpg?as=webp&width=800';
import heroSrcSet from './hero.jpg?as=webp&width=400,800,1200';
Advanced Configuration
// .parcelrc
{
"extends": "@parcel/config-default",
"transformers": {
"*.{jpg,jpeg,png}": ["@parcel/transformer-image"]
},
"optimizers": {
"*.{jpg,jpeg,png,webp,avif}": ["@parcel/optimizer-image"]
}
}
Comparison by Feature
Format Support
| Plugin | JPEG | PNG | WebP | AVIF | SVG |
|---|---|---|---|---|---|
| image-minimizer (Sharp) | Yes | Yes | Yes | Yes | Yes |
| responsive-loader | Yes | Yes | Yes | Yes | No |
| vite-imagetools | Yes | Yes | Yes | Yes | No |
| vite-plugin-image-optimizer | Yes | Yes | Yes | Yes | Yes |
| Parcel built-in | Yes | Yes | Yes | Yes | Yes |
Responsive Image Support
| Plugin | Multiple Sizes | Srcset | Placeholder |
|---|---|---|---|
| responsive-loader | Yes | Yes | Yes |
| vite-imagetools | Yes | Yes | Limited |
| image-minimizer | Manual | Manual | No |
| Parcel | Yes | Yes | No |
Build Performance
| Plugin | Speed | Memory Usage | Caching |
|---|---|---|---|
| Sharp-based | Fast | Moderate | Yes |
| Imagemin-based | Medium | High | Varies |
| Parcel built-in | Fast | Low | Yes |
| vite-imagetools | Fast | Low | Yes |
Configuration Examples
Production-Ready Webpack
// webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
const path = require('path');
module.exports = {
mode: 'production',
module: {
rules: [
{
test: /\.(png|jpe?g|gif|webp|avif)$/i,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 8 * 1024 // 8KB inline
}
},
generator: {
filename: 'images/[name].[contenthash][ext]'
}
},
{
test: /\.svg$/i,
type: 'asset',
generator: {
filename: 'images/[name].[contenthash][ext]'
}
}
]
},
optimization: {
minimizer: [
'...',
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.sharpMinify,
options: {
encodeOptions: {
jpeg: { quality: 80, mozjpeg: true },
png: { compressionLevel: 9, palette: true },
webp: { quality: 80, effort: 4 },
avif: { quality: 65, effort: 4 }
}
}
},
generator: [
{
preset: 'webp',
implementation: ImageMinimizerPlugin.sharpGenerate,
options: {
encodeOptions: {
webp: { quality: 80 }
}
}
},
{
preset: 'avif',
implementation: ImageMinimizerPlugin.sharpGenerate,
options: {
encodeOptions: {
avif: { quality: 65 }
}
}
}
]
})
]
}
};
Production-Ready Vite
// vite.config.js
import { defineConfig } from 'vite';
import { imagetools } from 'vite-imagetools';
import { ViteImageOptimizer } from 'vite-plugin-image-optimizer';
export default defineConfig({
plugins: [
// For query-based transforms
imagetools({
defaultDirectives: (url) => {
if (url.pathname.includes('hero')) {
return new URLSearchParams({
format: 'webp;avif',
w: '400;800;1200;1920',
quality: '80'
});
}
return new URLSearchParams({
quality: '80'
});
}
}),
// For automatic optimization
ViteImageOptimizer({
test: /\.(jpe?g|png|gif|webp|avif)$/i,
exclude: /node_modules/,
jpeg: { quality: 80 },
png: { quality: 80 },
webp: { quality: 80, effort: 4 },
avif: { quality: 65, effort: 4 },
cache: true,
cacheLocation: 'node_modules/.cache/image-optimizer'
})
],
build: {
assetsInlineLimit: 8192, // 8KB
rollupOptions: {
output: {
assetFileNames: (assetInfo) => {
const ext = assetInfo.name.split('.').pop();
if (/png|jpe?g|svg|gif|webp|avif/.test(ext)) {
return 'images/[name]-[hash][extname]';
}
return 'assets/[name]-[hash][extname]';
}
}
}
}
});
Responsive Images Setup
// vite.config.js with responsive images
import { defineConfig } from 'vite';
import { imagetools } from 'vite-imagetools';
const breakpoints = [320, 640, 960, 1280, 1920];
const formats = ['avif', 'webp', 'jpg'];
export default defineConfig({
plugins: [
imagetools({
defaultDirectives: (url) => {
const params = new URLSearchParams();
// Check if responsive is requested
if (url.searchParams.has('responsive')) {
params.set('w', breakpoints.join(';'));
params.set('format', formats.join(';'));
params.set('as', 'picture');
}
params.set('quality', '80');
return params;
}
})
]
});
// Usage in component
import { sources, img } from './hero.jpg?responsive';
// Generates picture element data
<picture>
{sources.map((source) => (
<source
key={source.type}
type={source.type}
srcSet={source.srcSet}
sizes="(max-width: 768px) 100vw, 50vw"
/>
))}
<img src={img.src} alt="Hero" />
</picture>
Sharp vs Imagemin
Sharp (Recommended)
Pros:
- Faster processing
- Native bindings (libvips)
- Better memory management
- AVIF support
- Actively maintained
Cons:
- Larger install size
- Platform-specific binaries
Imagemin
Pros:
- Modular (pick only what you need)
- More encoder options
- Smaller per-package size
Cons:
- Slower
- Some plugins unmaintained
- Complex dependency management
- Security concerns with older plugins
Recommendation
Use Sharp-based solutions for new projects:
// Sharp via image-minimizer-webpack-plugin
implementation: ImageMinimizerPlugin.sharpMinify
// Sharp via vite-imagetools
// Uses Sharp internally
// Direct Sharp
const sharp = require('sharp');
await sharp('input.jpg').webp({ quality: 80 }).toFile('output.webp');
Performance Tips
Caching
// Enable caching in Webpack
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.sharpMinify
},
// Cache processed images
loader: true
});
// Vite caching
ViteImageOptimizer({
cache: true,
cacheLocation: 'node_modules/.cache/images'
})
Parallel Processing
// Webpack parallel processing
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.sharpMinify
},
// Use available CPUs
concurrency: require('os').cpus().length
});
Excluding Large Files
// Exclude files over 10MB
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.sharpMinify,
filter: (source, sourcePath) => {
return source.length < 10 * 1024 * 1024; // 10MB
}
}
});
Troubleshooting
Common Issues
“Cannot find module ‘sharp’”
# Rebuild native modules
npm rebuild sharp
# Or install with specific platform
npm install --platform=linux sharp
Large bundle with images
// Check if images are inlined
// Adjust asset limit
{
parser: {
dataUrlCondition: {
maxSize: 4 * 1024 // 4KB limit
}
}
}
Slow builds
- Enable caching
- Reduce concurrent optimizations
- Exclude already-optimized images
- Use watch mode during development
Summary
Plugin Recommendations
| Use Case | Recommended |
|---|---|
| Webpack production | image-minimizer-webpack-plugin (Sharp) |
| Webpack responsive | responsive-loader |
| Vite general | vite-imagetools |
| Vite optimization | vite-plugin-image-optimizer |
| Parcel | Built-in optimizer |
| Universal | unplugin-imagemin |
Configuration Checklist
- ✅ Enable WebP/AVIF generation
- ✅ Set appropriate quality (75-85 for lossy)
- ✅ Configure caching for development
- ✅ Set asset inline limits
- ✅ Generate responsive sizes for key images
- ✅ Optimize SVGs separately
- ✅ Exclude already-optimized images
- ✅ Monitor bundle size impact
- ✅ Test output quality visually
- ✅ Verify build time is acceptable
Build tool image optimization automates what would otherwise be tedious manual work. Choose Sharp-based solutions for best performance, and configure responsive image generation for critical images.