gulp-imagemin and gulp-svgmin are Gulp plugins designed to reduce image file sizes during the build process. gulp-imagemin is a general-purpose optimizer that handles multiple formats like PNG, JPEG, GIF, and SVG by relying on various underlying compression libraries. gulp-svgmin is a specialized tool focused exclusively on SVG files, providing direct access to SVGO configuration options. Both tools integrate into Gulp streams to process assets before deployment, but they serve different scopes within an asset pipeline.
Both gulp-imagemin and gulp-svgmin are essential tools for reducing asset weight in Gulp-based workflows, but they solve different problems. gulp-imagemin acts as a generalist for all image formats, while gulp-svgmin is a specialist for vector graphics. Understanding their differences helps you build a faster, leaner build pipeline.
gulp-imagemin supports multiple image formats through a plugin architecture.
// gulp-imagemin: Handles multiple formats
import gulp from 'gulp';
import imagemin from 'gulp-imagemin';
export function optimizeAll() {
return gulp.src('src/images/*.{png,jpg,svg}')
.pipe(imagemin())
.pipe(gulp.dest('dist/images'));
}
gulp-svgmin supports only SVG files.
// gulp-svgmin: Handles SVG only
import gulp from 'gulp';
import svgmin from 'gulp-svgmin';
export function optimizeSvg() {
return gulp.src('src/images/*.svg')
.pipe(svgmin())
.pipe(gulp.dest('dist/images'));
}
gulp-imagemin uses a unified config object for all types.
// gulp-imagemin: Unified config
import imageminMozjpeg from 'imagemin-mozjpeg';
export function optimizeImages() {
return gulp.src('src/images/*')
.pipe(imagemin([
imageminMozjpeg({ quality: 80 }),
imagemin.svgo({ plugins: [{ removeViewBox: false }] })
]))
.pipe(gulp.dest('dist'));
}
gulp-svgmin exposes SVGO configuration directly.
// gulp-svgmin: Direct SVGO config
export function optimizeSvg() {
return gulp.src('src/images/*.svg')
.pipe(svgmin({
plugins: [
{ name: 'removeViewBox', active: false },
{ name: 'cleanupIDs', active: true }
]
}))
.pipe(gulp.dest('dist'));
}
gulp-imagemin often requires multiple dependencies.
imagemin-mozjpeg.imagemin-pngquant.package.json size but offers format-specific tuning.// gulp-imagemin: Multiple dependencies
import imageminPngquant from 'imagemin-pngquant';
export function images() {
return gulp.src('src/images/*')
.pipe(imagemin([
imageminPngquant({ quality: [0.6, 0.8] })
]))
.pipe(gulp.dest('dist'));
}
gulp-svgmin relies on a single core engine.
// gulp-svgmin: Single dependency
import svgmin from 'gulp-svgmin';
export function icons() {
return gulp.src('src/icons/*.svg')
.pipe(svgmin())
.pipe(gulp.dest('dist/icons'));
}
gulp-imagemin depends on native binaries for some formats.
mozjpeg or pngquant may require compilation on install.// gulp-imagemin: Potential native build issues
// npm install may trigger node-gyp rebuilds for underlying libs
gulp-svgmin is purely JavaScript-based.
// gulp-svgmin: Pure JS execution
// No native binaries required, smoother CI/CD setup
While they target different scopes, both plugins share core behaviors in the Gulp ecosystem.
.pipe().src and dest workflows.// Both use standard Gulp piping
return gulp.src('src/**/*')
.pipe(plugin()) // Works for imagemin or svgmin
.pipe(gulp.dest('dist'));
// gulp-imagemin: Quality setting
imagemin({ progressive: true, interlaced: true })
// gulp-svgmin: Precision setting
svgmin({ plugins: [{ removeUnusedNS: false }] })
// Both preserve critical SVG attributes by default
// <svg viewBox="0 0 100 100"> remains intact
// gulp-imagemin: Custom plugins array
imagemin([customPlugin()])
// gulp-svgmin: Custom SVGO plugins
svgmin({ plugins: [customSvgoPlugin] })
// Both preserve file relative paths
// src/logo.svg -> dist/logo.svg
| Feature | Shared by Both |
|---|---|
| Integration | 🌊 Gulp .pipe() streams |
| Goal | 📉 Reduce file size |
| Safety | 🛡️ Preserve visual quality |
| Config | 🔌 Customizable options |
| Ecosystem | 📦 npm hosted, Gulp compatible |
| Feature | gulp-imagemin | gulp-svgmin |
|---|---|---|
| Formats | 🖼️ PNG, JPEG, GIF, SVG | 📐 SVG Only |
| Engine | ⚙️ Multiple (mozjpeg, pngquant) | ⚙️ SVGO (JavaScript) |
| Setup | 📦 Multiple dependencies | 📦 Single dependency |
| Config | 🎛️ Unified options | 🎛️ Direct SVGO config |
| Install | 🐌 May need native builds | 🚀 Pure JS, faster install |
| Best For | 🌐 General asset pipelines | 🎨 Icon systems and vectors |
gulp-imagemin is like a Swiss Army knife 🔪 — great for handling every image type in one place. It is ideal for general websites where you have photos, logos, and backgrounds mixed together.
gulp-svgmin is like a scalpel 🪒 — perfect for precise work on vector graphics. It shines in projects where SVGs are critical, such as icon libraries or complex illustrations.
Final Thought: If you only have a few SVGs, gulp-imagemin is convenient. If SVGs are a core part of your design system, gulp-svgmin gives you the control you need.
Choose gulp-svgmin if your project relies heavily on SVG icons and requires fine-grained control over SVG cleanup rules. It offers deeper integration with SVGO, allowing you to toggle specific plugins like removing metadata or minifying styles. This is the better choice for design systems or component libraries where SVG consistency and size are critical.
Choose gulp-imagemin if you need a single plugin to handle all image types in your project, including photos and icons. It simplifies your Gulpfile by consolidating optimization logic for PNG, JPEG, and SVG into one step. This is ideal for standard websites where you want consistent compression across all static assets without managing multiple dependencies.
If you have any difficulties with the output of this plugin, please use the SVGO tracker.
With npm do:
npm install gulp-svgmin
import { src, dest } from 'gulp';
import svgmin from 'gulp-svgmin';
const defaultTask = () =>
src('logo.svg')
.pipe(svgmin())
.pipe(dest('./out'));
export default defaultTask;
By default, gulp-svgmin loads options from a svgo.config.js file in your project. See the svgo’s configuration docs for more info on how to write one.
You can control which directory svgo searches for svgo.config.js with the cwd option. Or you can use a different file name with the configFile option.
import { src, dest } from 'gulp';
import svgmin from 'gulp-svgmin';
const defaultTask = () =>
src('logo.svg')
.pipe(svgmin({
// Specify an absolute directory path to
// search for the config file.
cwd: '/users/admin/project/assets',
// This path is relative to process.cwd()
// or the 'cwd' option.
configFile: 'images/svg/config.js',
}))
.pipe(dest('./out'));
export default defaultTask;
Instead of using a config file, you can pass an object of svgo’s options to the gulp-svgmin plugin. You will need to provide the config in comma separated objects, like the example below.
const defaultTask = () =>
src('logo.svg')
.pipe(svgmin({
// Ensures the best optimization.
multipass: true,
js2svg: {
// Beutifies the SVG output instead of
// stripping all white space.
pretty: true,
indent: 2,
},
// Alter the default list of plugins.
plugins: [
// You can enable a plugin with just its name.
'sortAttrs',
{
name: 'removeViewBox',
// Disable a plugin by setting active to false.
active: false,
},
{
name: 'cleanupIDs',
// Add plugin options.
params: {
minify: true,
}
},
],
}))
.pipe(dest('./out'));
You can view the full list of plugins here.
By default, the plugins list given to the gulp plugin will alter the default list of svgo plugins. Optionally, you can specify your plugins and set the full flag to true to indicate that your plugins list should not be merged with the default list of plugins.
const defaultTask = () =>
src('logo.svg')
.pipe(svgmin({
multipass: true,
// The plugins list is the full list of plugins
// to use. The default list is ignored.
full: true,
plugins: [
'removeDoctype',
'removeComments',
'sortAttrs',
// ...
],
}))
.pipe(dest('./out'));
To have per-file options, pass a function, that receives file object and
returns svgo options. For example, if you need to prefix ids with filenames
to make them unique before combining svgs with gulp-svgstore:
const defaultTask = () =>
src('src/*.svg')
.pipe(svgmin(function getOptions(file) {
const prefix = path.basename(
file.relative,
path.extname(file.relative)
);
return {
plugins: [
{
name: 'cleanupIDs',
parmas: {
prefix: prefix + '-',
minify: true,
},
},
],
};
}))
.pipe(svgstore())
.pipe(dest('./dest'));
Pull requests are welcome. If you add functionality, then please add unit tests to cover it.
MIT © Ben Briggs