DEV Community

Max
Max

Posted on

Batch-Convert a Folder of Images to WebP with a Makefile (cwebp, No SaaS)

Batch-Convert a Folder of Images to WebP with a Makefile (cwebp, No SaaS)

Shipping WebP instead of JPEG/PNG is one of the cheapest web-perf wins there is — usually 25–35% smaller at the same visual quality. But nobody wants to hand-run cwebp on 200 files, and uploading a client's product photos to a random web tool is a non-starter.

Here's a tiny, local, dependency-light Makefile that converts every image in assets/ to WebP, skips files that are already up to date, and never touches the network.

1. Install cwebp

# Debian/Ubuntu
sudo apt install webp
# macOS
brew install webp
Enter fullscreen mode Exit fullscreen mode

2. The Makefile

Drop this in your project root:

SRC_DIR ?= assets
OUT_DIR ?= assets/webp
QUALITY ?= 80

SOURCES := $(wildcard $(SRC_DIR)/*.jpg $(SRC_DIR)/*.jpeg $(SRC_DIR)/*.png)
TARGETS := $(patsubst $(SRC_DIR)/%,$(OUT_DIR)/%.webp,$(SOURCES))

.PHONY: webp clean
webp: $(TARGETS)

$(OUT_DIR)/%.webp: $(SRC_DIR)/%
    @mkdir -p $(OUT_DIR)
    cwebp -quiet -q $(QUALITY) "$<" -o "$@"
    @echo "→ $@ ($$(du -h "$@" | cut -f1))"

clean:
    rm -rf $(OUT_DIR)
Enter fullscreen mode Exit fullscreen mode

3. Run it

make webp              # convert everything at q80
make webp QUALITY=90   # higher quality
make clean             # nuke the output dir
Enter fullscreen mode Exit fullscreen mode

Because targets depend on their source files, make only reconverts images that changed — so re-running it in a build pipeline is basically free.

4. Serve with a fallback

Let the browser pick WebP when it can, JPEG when it can't:

<picture>
  <source srcset="/assets/webp/hero.jpg.webp" type="image/webp">
  <img src="/assets/hero.jpg" alt="Hero" width="1200" height="600">
</picture>
Enter fullscreen mode Exit fullscreen mode

When you just need one file, fast

The Makefile is for repos and CI. When I just need to shrink or convert a single image by hand — pick a quality, preview the result, download — I use QuickShrink, which does the compression in the browser (the file never leaves your machine). Same privacy property as the local cwebp approach, no install.

Why bother

  • Smaller payload → faster LCP, better Core Web Vitals.
  • Local → client images never hit a third-party server.
  • Incrementalmake skips unchanged files, so it's cheap in CI.

That's the whole thing. No SaaS, no upload, ~15 lines of Makefile.

Top comments (0)