Updates:
Real optimization algorithms, not just encoder settings β with measured numbers
CLI automation: commit a config file, run one short command; --watch for dev loops
Building a dev tool or hiring developers? Get seen here. Become our Sponsor
Updates:
Real optimization algorithms, not just encoder settings β with measured numbers
CLI automation: commit a config file, run one short command; --watch for dev loops
Trivia: images are the web's biggest waste, and nobody looks.
Images are typically the heaviest thing on a page, and most sites ship them at a quality someone guessed once and never checked.
The sharpest example came out of this project's own tests. A dashboard screenshot at the industry-default "quality 80" WebP:
66 KB, with 3.3% of pixels visibly altered around glyph edges
The same image, encoded losslessly: 20 KB, bit-for-bit identical
So the default was 3Γ bigger and worse. Not a tradeoff β just a wrong guess, repeated billions of times.
That's the project. Not "compress harder" but measure instead of assume: look at each image, try a few ways, keep what's provably smallest at a quality you can verify.
The same lesson bit us twice more. SSIM, the metric everyone trusts, turned out to be blind to colour damage. And a denoising trick that looked like a 43% win died the moment it was measured fairly.
Guesses are expensive. Measuring is cheap.
The automation four
--skip-existing β incremental; unchanged files cost one stat()
--dry-run β measures savings, writes nothing
--watch [SECS] β re-optimises on change, default 2s
--json PATH β machine-readable output
Recipes
Build: image-optimizer src/images dist/images --skip-existing --quiet
Audit: image-optimizer src/images /tmp/check --dry-run --json audit.json
Dev loop: image-optimizer src/images dist/images --watch
Full: add --widths 1600,800,400 --svg --markup --base-url /assets/img
Other
Exit code non-zero on failure, so it gates a PR
--exclude GLOB repeatable; --preset NAME; --list, --list-presets, --list-formats
Reports: --csv, --html, --markup\
What changed (d019a87, 4 files, +557 lines)
projectconfig.py β new; finds and parses a project config file
cli.py β added --version, --list-settings, --config, --no-config, --init-config, --watch
test_projectconfig.py β new; 23 tests (231 total)
README.md β "Automating it locally" section
Setup
pip install -e . β puts image-optimizer on your PATH
image-optimizer --version β confirm it's installed
Config (do this first)
image-optimizer --init-config β scaffolds image-optimizer.toml
Commit it; the command finds it by walking up from wherever you run
--config PATH β use a specific file
--no-config β ignore any
--list-settings β every accepted key
Flags always beat the config file
Fewer billable hours. One run produces every responsive size plus the markup, replacing manual exports.
Accessibility compliance. WCAG alt text is written in, reducing ADA and EAA exposure.
Consistent brand. Logos stay sharp at any size as SVG, and screenshots stay pixel-perfect.
Proof for clients. Per-file reports quantify exactly what you saved.
No licence or API cost. Runs locally under MIT.
Benefits:
Lower hosting and CDN bills. Roughly 90% less image weight is a recurring cost cut.
More revenue per visitor. Images are usually the heaviest thing on a page, and faster pages convert better.
Better search ranking. Google scores Core Web Vitals, and the hero image is normally the LCP element.
Reach on weak connections. Mobile and emerging-market users stop abandoning half-loaded pages.
Updates:
Transparent-pixel colour β exported PNGs keep colour under erased (alpha 0) areas; invisible, but still encoded. Flattening it: 522 KB β 4.3 KB on WebP (β99%), β75% end to end.
Redundant channels β greyscale stored as RGB pays for two empty channels: β26% on PNG.
Chroma by measurement β SSIM is luma-only, so 4:2:0 moved it just 0.0004 while doing real colour damage. Now simulates the chroma round-trip and counts shifted pixels: photos 0.00%, coloured text 1.5β2%. β8% to β10% on images the old rule forced to 4:4:4, for ~1 ms.
Denoising rejected β looked like β43% until measured as size at matched SSIM; it lost at every target. Not shipped, documented as such.
Updates
Smart encoding β classifies each image, encodes several ways, keeps the smallest clearing an SSIM target. 58% β 89%.
Formats β AVIF/WebP/JPEG/PNG, auto picks smallest, never larger than source.
Fixed β EXIF orientation, ICCβsRGB, RGBAβJPEG crash.
Delivery β responsive widths, <picture> markup, HTML/JSON/CSV reports.
AI alt text via Claude, optional, off by default.
SVG tracing for logos with a gate that refuses bad traces.
SVG preview β side-by-side 1β8Γ, diff view, keep/discard/re-trace.
--dry-run measures real savings, writes nothing.
Changelog β Web Image Optimizer v2
Smart encoding: classifies each image, encodes several ways, keeps the smallest that clears an SSIM target. 58% β 89% reduction on fixtures.
Formats: AVIF + WebP + JPEG/PNG; auto picks smallest; never larger than source.
Fixed: EXIF orientation, ICCβsRGB, RGBAβJPEG crash.
Delivery: responsive widths, generated <picture>/srcset markup, HTML/JSON/CSV reports.
AI alt text via Claude, optional, off by default, key never stored.
SVG tracing for logos: palette cleanup, fidelity + colour-error gate, refuses photos/screenshots. Free and local.
SVG preview: side-by-side at 1β8Γ, diff view, keep/discard/re-trace.
Workflow: GUI rewrite with cancel and live results, CLI for CI, presets, incremental rebuilds.
163 tests; 10 real screenshots.
Web Image Optimizer
Measures instead of guessing: classifies each image (photo/graphic/screenshot), encodes it several ways, keeps the smallest that clears an SSIM target
92% smaller on the demo set β screenshots and logos come out pixel-identical, not smeared
AVIF + WebP + JPEG/PNG; auto keeps whichever is smaller; never writes a file bigger than your original
Fixes real bugs: EXIF orientation, ICCβsRGB conversion, RGBAβJPEG crashes
Responsive widths plus generated <picture>/srcset markup with width/height, lazy loading, alt text
Optional Claude alt text (WCAG-aware, off by default, key never stored)
HTML/JSON/CSV reports showing every decision and its SSIM
Desktop app + CLI for CI; presets, parallel, cancellable, incremental rebuilds
Building a dev tool or hiring developers? Get seen here. Become our Sponsor