Cet article n'est actuellement disponible qu'en anglais.

CLIApr 5, 20269 min read

CLI Tools to Batch Convert Images to WebP in 2026

You have a folder full of images. Maybe it is 50 product photos, maybe it is 500 screenshots from a documentation site. You need them all converted to WebP. You want a CLI tool that handles it in one command.

But which one should you reach for?

Four practical options tend to come up in 2026: cwebp, ImageMagick, Sharp, and GetWebP. Each has real strengths and real weaknesses. This article puts them side by side with benchmark context, install commands, and batch conversion syntax so you can make a defensible choice for your workflow.

Ranking these tools without preserving versions, operating systems, input types, commands, failure modes, or maintenance cost would not support a real decision. Treat the sections below as decision evidence, not a universal leaderboard. The right CLI depends on your image set, CI environment, native dependency tolerance, and whether you need a converter or a broader image-processing library.

The Contenders#

cwebp (Google's Reference Encoder)#

Google built the WebP format, and cwebp is their official command-line encoder. Google's cwebp documentation covers the available encoding options. The tool does one thing well: convert an image to WebP. If you want folder traversal, progress reporting, or mixed-format batch handling, you usually add shell scripting around it.

ImageMagick#

ImageMagick is a broad image-processing suite with many format and transformation options. Its format documentation shows how wide the tool's scope is. It is powerful, but that power comes with more configuration surface. In Docker and CI environments, install size and policy configuration can become part of the maintenance cost.

Sharp (Node.js)#

Sharp wraps the native libvips library in a clean Node.js API. It is fast in many workflows because it delegates the heavy lifting to compiled code. The Sharp installation documentation is worth reading before putting it in CI because platform, Node version, architecture, and container base image can affect setup.

GetWebP#

GetWebP takes a different approach. It uses a WebAssembly-based encoder path and ships through npm without native build dependencies. No node-gyp, no libvips, no platform-specific binary setup in the project. The trade-off is speed: WASM is usually slower than native code. The install story is simpler when Node.js 18+ is available, especially if your workflow already standardizes on npm. The local-processing model is covered in the security overview, and the CLI flags are documented in the command reference.

Installation Comparison#

This is where the tools start to diverge in a meaningful way.

cwebp:

# macOS
brew install webp

# Ubuntu/Debian
apt install webp

# Windows
# Download precompiled binaries from Google, add to PATH manually

Platform-specific. Different commands on every OS. Windows requires manual binary management.

ImageMagick:

# macOS
brew install imagemagick

# Ubuntu/Debian
apt install imagemagick

# Installs a larger image-processing dependency set

Large install surface. Works across many environments, but the policy.xml file can block PDF and SVG processing by default for security reasons. Debugging those environment-specific policy differences in CI can become part of the maintenance cost.

Sharp:

npm install sharp

Looks simple. Works well when the native package path matches your platform. Sharp downloads pre-built native binaries for your specific OS, architecture, and Node version. If there is no match, it can fall back to building from source with node-gyp, which requires Python and a C++ compiler. In Docker, this can mean extra build dependencies for a node:alpine image and longer builds.

GetWebP:

npx -y getwebp .

The npx command downloads and runs GetWebP in one step. There are no native dependencies or build steps in the project. In practice, that makes it easier to use across developer machines, Docker images, and CI runners where Node.js 18+ is available.

Batch Conversion Syntax#

The real test: "convert every image in this folder to WebP." Here is how each tool handles it.

cwebp:

for f in *.jpg; do
  cwebp "$f" -o "${f%.jpg}.webp"
done

You need a separate loop for each file extension. Want to handle PNG too? Add another loop. Want recursive directory scanning? Wrap it in find. Want progress output? Add echo statements. You are basically writing a bash script every time.

ImageMagick:

magick mogrify -format webp *.jpg

Cleaner, but limited. This converts files in the current directory only — no recursion. All output goes to the same directory. If you want to customize quality per format or handle mixed input types, you are back to scripting.

Sharp:

// convert.js
const sharp = require('sharp');
const fs = require('fs');
const path = require('path');

const dir = './images';
const files = fs.readdirSync(dir).filter(f => /\.(jpg|png)$/i.test(f));

(async () => {
  for (const file of files) {
    const input = path.join(dir, file);
    const output = path.join(dir, file.replace(/\.(jpg|png)$/i, '.webp'));
    await sharp(input).webp({ quality: 80 }).toFile(output);
  }
})();

At minimum, you are writing 10+ lines of JavaScript. Want recursion? Add a directory walker. Want progress bars? Add a dependency. Want error handling? More code. Sharp is a library, not a tool — the ergonomics are up to you.

GetWebP:

# Convert all images in a directory (recursive)
npx -y getwebp ./images --quality 80 --recursive --json

One command. Pass --recursive for directory traversal and --json when you want machine-readable evidence from the run. By default, GetWebP writes WebP files beside the originals and keeps the source files unchanged. For CI or review workflows, save the NDJSON stream described in the JSON output reference.

Sample Benchmark: Real Numbers on Real Images#

The table below is a directional local sample, not a reusable vendor benchmark. Treat these numbers as sample results rather than universal performance guarantees; image content, CPU, container base image, encoder flags, tool versions, and parallelism can change the outcome. If the numbers will influence a production decision, rerun the test on your own corpus and keep the exact commands and versions with the report.

ImageInput SizeGetWebPSharpImageMagick
320x240 JPEG40 KB206ms / 11 KB89ms / 11 KB33ms / 11 KB
640x480 JPEG138 KB252ms / 34 KB114ms / 34 KB60ms / 34 KB
800x600 PNG2.4 MB324ms / 45 KB150ms / 45 KB92ms / 45 KB
1024x768 PNG3.9 MB390ms / 64 KB192ms / 64 KB132ms / 64 KB
1024x768 JPEG302 KB360ms / 70 KB161ms / 70 KB110ms / 70 KB
1920x1080 JPEG768 KB643ms / 163 KB331ms / 163 KB276ms / 163 KB
2048x1536 PNG15.6 MB975ms / 201 KB495ms / 201 KB419ms / 196 KB
4096x3072 JPEG3.8 MB2736ms / 730 KB1196ms / 730 KB1250ms / 730 KB

Time = wall-clock conversion time for one image conversion in this sample run. Output size = resulting WebP file size. The useful way to repeat this test in your own project is to keep the input folder, quality setting, tool versions, machine type, and command output together in the same note or pull request.

The pattern in this sample is clear: Sharp and ImageMagick are faster in this run. They use native compiled code, and that can matter for throughput. GetWebP is slower in this table, which is the expected trade-off to evaluate when avoiding native image dependencies.

The output sizes are close in this sample, but do not treat that as proof that every image class will behave the same way. Product photography, screenshots, UI gradients, transparent PNGs, and marketing artwork can respond differently to the same quality value. Before changing a production pipeline, inspect representative outputs and keep the conversion logs.

For a typical batch of 100 images, the difference might be a few minutes. In a nightly CI job that may be acceptable; in a build that blocks every deploy, it may not be. That decision should come from your own build budget, not from a generic benchmark.

The Real Trade-off#

Let's be honest about what you are choosing between.

If raw speed is everything and you control the environment, Sharp is often the strongest option. You know your target OS. You know your Node version. You can ensure libvips installs cleanly. In that scenario, Sharp is fast, produces great output, and has a solid API.

If you need a short npm-based command with no native project dependency, GetWebP is a good candidate. CI runners with unpredictable base images. Docker containers you did not build. A teammate's Windows laptop. A GitHub Action that should stay simple. In these scenarios, the zero-dependency approach can remove a real class of setup problems.

If you are on a server you fully control and want maximum flexibility, ImageMagick is a strong candidate. It handles a very broad set of formats, and once it is installed and configured, its behavior can be made predictable.

If you just need to convert one file, cwebp is fine. It is small, focused, and does exactly what it says.

The hidden cost that benchmarks do not capture is the install tax. That is the 45 minutes you spend debugging why Sharp cannot find libvips in your Alpine container. Or the hour you lose because ImageMagick's policy.xml blocks WebP encoding in your CI environment. Or the frustration of writing platform-specific install scripts for cwebp across macOS, Ubuntu, and Windows runners.

GetWebP's value proposition is not raw speed. It is reducing setup risk in environments where native image dependencies are a recurring source of friction. A useful decision record looks like this:

Decision: test GetWebP for docs and static site assets
Reason: Node-based CI, no native image dependency budget
Command: npx -y getwebp ./public/images --output ./public/images-webp --recursive --json
Evidence: conversion.ndjson, visual review of hero images, screenshots, and logos
Rejected for now: Sharp, because this workflow does not need runtime transforms
Review again if: conversion time becomes a deploy blocker or runtime resizing is required

Verdict and Quick Start#

For many developers who need to batch convert images to WebP from the command line, GetWebP offers a practical balance of simplicity and reliability. It is slower than native tools in the benchmark above, but it removes much of the setup friction that can make native tools painful in multi-platform development workflows.

Here is how to get started:

# Convert all images in current directory to WebP
npx -y getwebp .

# Specify a directory and quality level
npx -y getwebp ./images --quality 80 --json

The free tier converts up to 20 images per invocation with a short pause between files — enough for most personal projects and testing. The Pro tier removes both the per-run cap and the inter-file delay for teams and production pipelines.

If speed is your main concern and you are willing to manage native dependencies, Sharp or ImageMagick may serve you well. If you value a short command, no native build step, and predictable setup in Node-based workflows, GetWebP is worth testing on your own image set before committing to a pipeline. For automated checks, wire the command into your build using the CI integration guide and keep the JSON log as review evidence.

Jack avatar

Jack

GetWebP Editor

Jack writes GetWebP guides about local-first image conversion, WebP workflows, browser compatibility, and practical performance checks for teams that publish images on the web.