Using it in CI
Exit codes, --json, and progress output in a non-interactive environment.
The tool is built to behave predictably with no terminal attached — every human-facing behavior degrades explicitly rather than assuming a TTY.
Progress never pollutes a log
The rewriting progress line (photo.jpg · attempt 4 · best 48.2 KB) only ever prints when stderr
is a real TTY. Piped or redirected — exactly what a CI runner does — it’s silent automatically,
with or without --quiet. You don’t need --quiet to keep a CI log clean; it exists for
suppressing the plain messages (missing-file reports, target-unreachable suggestion sentences,
the --accept-closest warning), which print regardless of TTY because a script reading a log file
is still owed the reason a file failed.
Exit codes are the contract
A CI step branching on $? gets a specific, stable number for every outcome — see
Exit codes for the full table. The common shape:
imagekbreducer compress src/*.jpg --to 80kb --out dist/img --quiet
if [ $? -ne 0 ]; then
echo "one or more images could not be compressed under budget"
exit 1
fi
With multiple inputs, the process exits with the first failure’s code in input order — use
--json (below) if you need to know which specific file(s) failed and why, rather than just that
something did.
--json for a machine-readable result
imagekbreducer compress src/*.jpg --to 80kb --out dist/img --json > result.json
jq -e '.ok' result.json > /dev/null || {
jq -r '.results[] | select(.ok == false) | "\(.input): \(.error.message)"' result.json
exit 1
}
See --json output for the full envelope shape.
--dry-run to check without writing
Useful for a “would this pass budget” step that shouldn’t leave build artifacts behind:
imagekbreducer compress screenshot.png --to 100kb --dry-run --json | jq '.results[0].resultBytes'
The reported resultBytes is the real number a real run would produce — nothing is fabricated for
a dry run.
A full budget-gate recipe
See Recipes → Page-weight budget in CI for a worked example that fails a build when a committed image is over budget, and Recipes → Pre-commit hook for catching the same thing before it’s even committed.
--help/--version never load the engine
imagekbreducer --help and imagekbreducer --version return before the wasm codec ever loads —
useful for a CI cache-warming step or a version-pin check that shouldn’t pay the cost of loading
every codec just to print a string.