Lighthouse tells you your images are too big. ImgTune measures every image on the live page at six viewports, gives the sizes, quality and format to set, and checks each quality target with SSIMULACRA2. Run against your dev server, it also points at the component, file and line that renders each image. Your coding agent applies the fix, and a rescan checks it. Open source, MIT.
Works with your image CDN. Cloudinary, imgix and next/image resize to whatever width sizes asks for, so a wrong sizes is waste no CDN removes.
Built for image-heavy sites: e-commerce catalogs, media, marketplaces.
$ npx imgtune scan https://your-site
Nothing leaves your machine except the requests your own site makes.
Drop an image. See what it weighs at every width it is shown.
Runs in this browser. The file is never uploaded. Click to choose one.
1
Scan loads each page at six viewports and records every image.
2
Hints give each image its sizes, quality and format, the bytes each fix saves, and, when they resolve, the file and line in your source.
3
Your agent fixes it in your source, and a rescan checks every change.
Two ways to measure.
01 / check and audit
check
$ npx imgtune check https://your-site
The production check, in a browser only, for any live site, yours or a prospect's. It surveys the site's sitemap, groups pages by route type and deep-scans the heaviest page of each type. The report is a ready Markdown file for performance agencies and consultants.
The deep mode for your own Next.js app. It reads the app's routes and next.config, measures the production build, and with --dev locates each fix at its file and line in the source.
In CI, the GitHub Action comments on each pull request with the image weight of each page, its savings and the top fix hints, and can fail the job above a fail-over budget.
Scanned 2026-10-30 with imgtune 0.1.0 (tool commit 14b3c12), six viewports, SSIMULACRA2 delta 2, page fully scrolled. The hatched part of the estimate is a local re-encode, not a measured file (see how it is measured). The 15% line is the study's bar. Slot is the CSS width the image fills, needed is the device pixels it needs (widest viewport), served is the file's own width.
A1 · production3,250KB / view
estimated saving 33.2%
A2 · production1,263KB / view
estimated saving 53.1%
A3 · production3,355KB / view
estimated saving 38.2%
A4 · production9,254KB / view
estimated saving 35.9%
A5 · production7,714KB / view
estimated saving 16.5%
A6 · production9,078KB / view
estimated saving 27.7%
Production sites are anonymous: no names, images or URLs. Study v4 numbers, from the study's results.
Width, per viewport.
03 / layout presets or a sizes value
An image is only as big as the pixels its slot needs. Pick how the image is laid out, and the table gives the device pixels it needs at each of the CLI's six viewports. The demo scores the encodings at those widths.
viewport
css px
dpr
needed px
iphone-se
375
2x
750
iphone-15
390
3x
1170
pixel-7
412
2.625x
1082
iphone-15-pro-max
430
3x
1290
desktop
1440
2x
2880
desktop-1280
1280
1x
1280
Needed px = CSS width x dpr, rounded up. Viewports and dpr are the CLI's six.
One lever is not enough.
04 / size, quality, format
An image is as heavy as its pixels, its quality and its format together. Fix one and the other two keep the waste.
1
Compressors squeeze the file you hand them, but never learn how wide it is shown. A 6,000 px logo in a 150 px slot stays 6,000 px, only better compressed.
2
Image CDNs and next/image resize on request, but only to the widths your sizes attribute asks for. Get sizes wrong, or leave it out, and the browser fetches a file several times too wide, on every phone.
3
Lighthouse flags oversized, poorly encoded and old-format images, at one viewport per run, with a fixed estimate. It tells you something is wrong; it does not tell you which sizes or quality to set.
→
ImgTune measures size, quality and format together, per image, on the live page at six viewports. Every candidate is checked with SSIMULACRA2, so a saving only counts when nobody can see the difference. ImgTune does not edit your code: your AI agent makes the change from the hint, and a rescan checks it. That works in any framework.
survey200 production sites on many stacks, anonymous. The median site's estimated saving is 16.7% of its image bytes.
1,830KBmedian image weight per view
16.7%median estimated saving
42.0%of sites could save 20% or more84 of 200 sites