DEV Community

loading...

Convert multiple images to WebP in JavaScript

Waldek Mastykarz
Cloud Developer Advocate at Microsoft focusing on Microsoft 365, Microsoft 365 Patterns and Practices member
Originally published at blog.mastykarz.nl on ・3 min read

Convert multiple images to WebP in JavaScript

A while back I wrote about how you can convert multiple images to WebP using PowerShell. Here's how you can do the same using JavaScript.

Improve your website performance with WebP

WebP is a great format for images on the web that can help you improve the performance of your web app or site. I use images a lot when writing and if I look at my images, WebP is typically significantly smaller.

List of images showing jpg/png images and their webp equivalent and their sizes in comparison

Convert multiple images to WebP using PowerShell

Recently I showed you how you can convert multiple images to WebP using PowerShell. With a short script, you'd grab images modified in the last hour and convert them to WebP using Google's cwebp tool.

If you don't use PowerShell regularly, starting it up just for this task would be tedious. So rather than having to install PowerShell, here's how you can do this using JavaScript from bash, zsh, fish, or any other shell.

Convert multiple images to WebP using JavaScript

Here's a simple script built using JavaScript that takes files modified in the last hour and converts them to WebP using cwebp. To run it, you need to have installed Node.js and Google's zx. Save the file on your disk with the .mjs extension and for ease of use alias it with something like cwebps (the s in the end indicating you'll be converting multiple files). Don't forget to make the script executable by running chmod +x ./script.mjs.

#!/usr/bin/env zx

const fs = require('fs'),
  path = require('path');

const nonWebPFiles = fs
  .readdirSync(process.cwd())
  .filter(file => !file.endsWith('.webp'));
const lastHour = new Date();
lastHour.setHours(lastHour.getHours() - 1);

nonWebPFiles.forEach(file => {
  fs.stat(file, (err, stats) => {
    if (err) {
      throw err;
    }

    if (stats.isDirectory() ||
      stats.mtime < lastHour) {
      return;
    }

    const fileNameWithoutExtension = path.basename(file, path.extname(file));
    $`cwebp ${file} -o ${fileNameWithoutExtension}.webp`;
  });
});

Enter fullscreen mode Exit fullscreen mode

Let's have a look at what the script does line by line. We start with a shebang (#!/usr/bin/env zx) pointing to zx so that your shell knows how to execute the script when you call ./script.mjs in your terminal. Next, we load fs and path to get access to filesystem functions in Node.js. With prerequisites in place, we start the script.

First, we get the list of files in the current directory. We exclude files with the .webp extension. Next, we define the timestamp for one hour ago. This will help us include only files that we've worked with recently. If you want to use this script differently you'll need to modify or remove this line.

Then, we iterate through the list of files. For each file, we get its metadata. If the file is a directory or has been modified more than one hour ago, we skip it. Next, we get the file's name without its extension and we end up calling the cwebp tool to convert the image.

That's it! You can now easily convert multiple images to WebP with just one command.

Discussion (0)