Skip to content
Image KB Reducer
Esc
↑↓navigate↵open⌘Jpreview
On this page

Pre-commit hook

Catch an oversized image before it's even committed.

Catching an over-budget image in CI (see Page-weight budget in CI) means it already made it into a commit — and, if the check only warns, possibly into the repo’s history for good. A pre-commit hook catches it before that ever happens.

Plain git hook

.git/hooks/pre-commit (or install via Husky / pre-commit if the repo already uses one):

#!/usr/bin/env bash
set -euo pipefail

BUDGET="200kb"
staged=$(git diff --cached --name-only --diff-filter=ACM -- '*.jpg' '*.jpeg' '*.png' '*.webp')
[ -z "$staged" ] && exit 0

for file in $staged; do
  bytes=$(wc -c < "$file")
  # Cheap check first: if it's already under budget, no need to spend a
  # real compression attempt on it.
  if [ "$bytes" -le 204800 ]; then continue; fi

  echo "compressing $file (currently ${bytes} bytes, over the ${BUDGET} budget)..."
  if ! npx imagekbreducer compress "$file" --to "$BUDGET" --in-place --quiet; then
    echo "error: $file cannot be brought under ${BUDGET} -- commit blocked."
    echo "run 'imagekbreducer compress $file --to $BUDGET --accept-closest --in-place' to see how close it gets, or raise the budget for this file."
    exit 1
  fi

  git add "$file"
done

--in-place is deliberate here, not a default worth being casual about: it’s the only flag that overwrites the working file directly, which is exactly what you want in a pre-commit hook (the recompressed bytes need to be what actually gets committed) and exactly what you don’t want anywhere a mistake would be expensive — see Output files for the guard rails around it, and don’t reach for --in-place in a CI step running against a checkout you don’t control.

Husky

npx husky init

.husky/pre-commit:

#!/usr/bin/env sh
. "$(dirname "$0")/_/husky.sh"

npx --no-install imagekbreducer --version > /dev/null 2>&1 || npm install --no-save imagekbreducer
sh scripts/check-image-budget.sh

(with the loop above saved as scripts/check-image-budget.sh, chmod +x’d).

What this trades off

A pre-commit hook that recompresses adds latency to every commit that touches an image — usually well under a second per file for the search this tool runs, but noticeable on a large batch. If that’s not acceptable, use the check-only variant from Page-weight budget in CI as a pre-commit hook instead (swap --in-place for --dry-run and drop the git add), and let CI be the place that actually fixes the file, or blocks the merge until a human does.

Was this page helpful?