The Mijingo Blog

Latest news, updates, free tutorials, and more from Mijingo.

Optimizing Images with Grunt & Gulp

by Ryan Irelan

In the JavaScript Task Runners course, we converted Sass to CSS, compressed JavaScript, watched files for changes, and more.

Let’s look at how we can optimize the image assets we use in our web development projects.

Optimizing images helps us keep our sites as speedy as possible. By automating the optimization we can just drop an image in to our project and our task runner will ensure it is as small as possible without loss of quality.

We’ll start with Grunt first, and then move to Gulp.

Optimizing Images in Grunt

We’ll use the popular Grunt plugin grunt-contrib-imagemin. Let’s install that and save it as local project dependency.

npm install grunt-contrib-imagemin --save-dev

Now we need to load that plugin in our Gruntfile.js file. If you’re still working in the sample project, you can place this below the other plugins we’ve loaded.


Just like with our other Grunt tasks, we name the task after the plugin. In this case, our task will be called imagemin. We then need to define the options for the task by specifying in which directory Grunt should look to find image files to process.

Here’s the code for the task:

imagemin: {
    jpgs: {
        options: {
            progressive: true
        files: [{
            expand: true,
            cwd: 'src/img',
            src: ['*.jpg'],
            dest: 'images/'

We start with the task wrapper for the imagemin task, and then create a target for processing JPG images. The JPG processing in grunt-contrib-imagemin has one option, progressive, which takes a boolean as the value.

We must also tell imagemin where the source images are and where they need to end up. This is very similar to what we did during the course with our JavaScript and Sass/CSS files in our other tasks.

grunt-contrib-imagemin allows us to do this by either statically or dynamically.

  • Statically: we define a dictionary of specific files (names and extensions) to process.
  • Dynamically: we specify a source directory, patterns to match files (like *.jpg), and then a destination directory.

I like flexibility, so we’re using the dynamic approach in this example.

First, we set the expand (dynamic expansion) option to true. This is required to use dynamic matching.

We then set the current working directory (cwd) to our source image directory. Using the src property, we match all files ending in .jpg in our current working directory.

Finally, we tell Grunt to drop the optimized files in to images directory, which is located in our project root (and relative to the Gruntfile.js file).

If you don’t have the src/img directory already created, you’ll need to do that. Download this sample JPG image to use as a test.

From the command line, let’s run the task to test it out.

grunt imagemin

This runs our imagemin task and processes any .jpg files found in the src/img directory in our project.

If all worked properly, you should see this output from Grunt:

Running "imagemin:jpgs" (imagemin) task
Minified 1 image (saved 12.84 kB)

Done, without errors.

Optimizing Images in Gulp

This version of optimizing images will go faster because we’ve covered most of the basics in the Grunt tutorial above. Now let’s see how this applies to Gulp.

Install the imagemin plugin for Gulp.

npm install gulp-imagemin --save-dev

Require gulp-imagemin in our gulpfile.js file:

var imagemin = require('gulp-imagemin');

And then create our Gulp task to process the images:

gulp.task('jpgs', function() {
    return gulp.src('src/img/*.jpg')
    .pipe(imagemin({ progressive: true }))

Let’s review how this works.

We are calling the task jpgs and then passing in a source location of any files in src/img that have the .jpg extension.

Then we run imagemin with the progressive option enabled. Finally, we have Gulp drop the processed image in the images directory.

Make sure your source image (this sample JPG image will work just fine) is in place and then run gulp to process it.

gulp jpgs

You should see output similar to this:

[09:10:50] Using gulpfile gulpfile.js
[09:10:50] Starting 'jpgs'...
[09:10:51] gulp-imagemin: Minified 1 image (saved 12.84 kB - 6.6%)
[09:10:51] Finished 'jpgs' after 108 ms

Hooray, you did it!

Further Reading

For enhancements to the code above, I encourage you to read the official documentation for each of the imagemin plugins.

If you want to learn more about the JavaScript Task Runners Grunt and Gulp, our 90 minute course will get your up and running quickly.

Filed Under: Free Tutorials, JavaScript Task Runners