Optimize and Transform Images in Node.js with Sharp

Zebra image getting filled in witha paint bucket

Image optimization is crucial for maintaining fast website performance and providing a smooth user experience.

One popular open-source library for image processing is Sharp.js, a high-performance Node.js module that allows you to resize, convert, and manipulate images easily.

In this tutorial, I will go over the most common use cases I've seen for using Sharp so that you can get going faster.

Prerequisites

  • Some basic Node.js knowledge
  • Node.js version >= 14.15.0

Installation

npm install sharp

Or with yarn:

yarn add sharp

Resizing Images

Resizing is a standard operation for image optimization. With Sharp.js, you can resize images easily while maintaining their aspect ratio. Here's an example of resizing an image:

const sharp = require('sharp');

// Pass the image you want to manipulate to sharp
sharp('images/input.jpg')
  .resize(800, 600) // Dimensions (width, height)
  // name your output file eg. output.jpg
  .toFile('images/output.jpg', (err, info) => {
    if (err) {
      console.error(err);
    } else {
      console.log(info);
    }
  });

For the first example, I want to show you that you can also get more granular. Here's how you pass optional settings to sharp.

The full docs can be found here for the different configurations.

Format Conversion

Sharp.js supports various image formats, including JPEG, PNG, WebP, and AVIF. Converting images to newer formats like WebP or AVIF can significantly reduce file size.

Here's an example of converting a JPEG image to WebP:

const sharp = require('sharp');

sharp("images/input.jpg")
  .webp({ quality: 80 }) // Optional to change quality for more performance gainz
  .toFile("images/output.webp", (err, info) => {
    if (err) {
      console.error(err);
    } else {
      console.log(info);
    }
  });

Compression and Quality

Sharp.js supports various compression options for different image formats. For example, when working with PNGs, you can set the compression level.

const sharp = require('sharp');

sharp("images/input.png")
  .png({ quality: 80, compressionLevel: 8 }) // zlib compression level, 0 (fastest, largest) to 9 (slowest, smallest)
  .toFile("images/output.png", (err, info) => {
    if (err) {
      console.error(err);
    } else {
      console.log(info);
    }
  });

This is a very simplistic example, but there are far too many compression and quality options to cover in this tutorial, so I recommend checking out the docs here to get all the options.

Additional Features

Sharp also provides various features like cropping, rotating, and applying filters. Here's an example of cropping an image to a specific region:

const sharp = require('sharp');

sharp("images/input.jpg")
  // extract the following section of the image to output
  .extract({ left: 100, top: 50, width: 400, height: 300 })
  .toFile("images/output.jpg", (err, info) => {
    if (err) {
      console.error(err);
    } else {
      console.log(info);
    }
  });

This is just a tiny subset of the additional features you can get from Sharp. Jump into the docs, and you'll find a tonne more features that you can use to get the perfect picture for your app!

Chaining Operations

Bring it all together!

One of the powerful features of Sharp.js is its ability to chain multiple operations together. For instance, you can resize, compress, and convert an image in a single chain:

const sharp = require('sharp');

sharp("images/input.jpg")
  .resize(800, 600)
  .webp({ quality: 80 })
  .toFile("images/output.webp", (err, info) => {
    if (err) {
      console.error(err);
    } else {
      console.log(info);
    }
  });

In this example, we're resizing the input image to 800x600 pixels, converting it to the WebP format, and setting the quality to 80.


In this tutorial, we've covered the basics of image optimization using Sharp.js, including resizing, compression, format conversion, and additional features like cropping and chaining operations.

Sharp is a versatile and powerful tool for image processing, making it an excellent choice for optimizing images in your Node.js projects.


Follow me on Twitter or connect on LinkedIn.

🚨 Want to make friends and learn from peers? You can join our free web developer community here. 🎉

NodejsPerformanceJavaScriptNodeJS
Avatar for Niall Maher

Written by Niall Maher

Founder of Codú - The web developer community! I've worked in nearly every corner of technology businesses; Lead Developer, Software Architect, Product Manager, CTO and now happily a Founder.

Loading

Fetching comments

Hey! 👋

Got something to say?

or to leave a comment.