Images: conversion and resizing
ee-deploy can do two things to your site’s images while it packages them. Both are off unless you turn them on, and both change only what’s deployed, never your build output or your repository.
- Convert JPEG and PNG images to WebP or AVIF, and rewrite every page, stylesheet, feed and rule that names them. See Converting to WebP or AVIF.
- Resize JPEG and PNG images wider than a limit you set, keeping their names and formats. See Scaling down wide images.
You can use either one, or both. With both, images are resized first and the smaller files are converted.
Both work from the command line, the GitHub Action and the Astro integration. They need @evolving-edge/ee-cdn-cli 0.4.0 or later and a recent packaging tool: see Which version you need.
Converting to WebP or AVIF
Section titled “Converting to WebP or AVIF”npx @evolving-edge/ee-cdn-cli --domain www.example.com --images webpEach JPEG and PNG becomes a WebP or AVIF file with the same name and the new extension (photo.jpg becomes photo.webp). Every reference to it in your HTML, CSS, JavaScript, feeds, sitemaps, _redirects and _headers is rewritten to the new name. Only the extension changes, so query strings, srcset widths and the rest of each address stay exactly as written.
An image converts only if every reference to it can be rewritten safely. An image whose old name would still be loaded somewhere is left as it is, so no page loses an image.
WebP or AVIF
Section titled “WebP or AVIF”| WebP | AVIF | |
|---|---|---|
| Default quality for photographs | 80 | 60 |
| PNGs, by default | Lossless | Lossless |
| Speed | Faster | Several times slower |
Social preview images (og:image, twitter:image) |
Converted | Left as they are, because most social sites can’t read AVIF |
WebP is the better choice for most sites, and for any site where the photos are also its social preview images.
Options
Section titled “Options”| Option | Flag | In ee.jsonc |
|---|---|---|
| Format | --images webp, --images avif |
"images": "webp" |
Turn it off, overriding ee.jsonc |
--images off |
"images": "off" |
| Other hosts the site is served from | --image-host <host>, once per host |
"hosts": ["cdn.example.com"] |
| Quality for lossy encodes, 1 to 100 | — | "quality": 75 |
| PNGs: lossless or lossy | — | "png": "lossy" |
| Write the full report as JSON | --image-report <file> |
— |
In ee.jsonc, give the format alone, or an object with a format and its settings:
// ee.jsonc, in the folder you publish{ "images": { "format": "webp", "quality": 75, "png": "lossless", "hosts": ["cdn.example.com"] }}A flag wins over ee.jsonc. A quality in ee.jsonc applies only to the format it’s written with, because the two formats’ quality scales differ. An images setting ee-deploy doesn’t understand stops the deploy, naming the line.
Your site’s own addresses: an absolute address such as https://www.example.com/img/photo.jpg is rewritten only if its host is one of the site’s: the --domain you deploy to, the domain in ee.jsonc, any --image-host or "hosts", and each one’s www. or bare twin. An image named by an address on any other host is left as it is, with a warning naming that host, so you can add it.
What’s left as it is
Section titled “What’s left as it is”ee-deploy prints a summary, for example Images: 412 of 450 converted to webp, and says why the rest were left alone, counted by reason. --image-report writes every image and its reason to a JSON file.
The common reasons:
- Not smaller: the converted file wasn’t smaller than the original. This is common for small images and for images your generator already compressed.
- Can’t be converted faithfully: animated PNGs, CMYK JPEGs, 16-bit PNGs, images over 40 megapixels, and images with a colour profile other than sRGB (Display P3, Adobe RGB), whose colours would shift.
- A reference can’t be rewritten safely:
- a script builds the image’s name in code;
- the name is written in an escaped form;
- it’s named by an address on a host that isn’t the site’s;
- a file under an immutable folder (
_astro/,_next/static/and the like) names it; - a file protected by an
integrityhash names it; - a
type,lengthor file size declared beside the reference would become false.
- Read by something other than a browser:
apple-touch-iconand Windows tile images, and, with AVIF, social preview images. - Grouped with an image that stays: the images in one
srcset,<picture>orimage-set()convert together or not at all.
Old image addresses
Section titled “Old image addresses”After conversion, photo.jpg no longer exists on the site, so a link to it from elsewhere (another site, a feed reader’s saved copy, an image search result) gets a 404. Packaging doesn’t add redirects.
To keep an old address working, add a rule to _redirects, for example /img/photo.jpg /img/photo.webp 301. Redirect rules apply to Level 0 sites only, so on a Level 1 or Level 2 site an old image address simply stops working.
Scaling down wide images
Section titled “Scaling down wide images”npx @evolving-edge/ee-cdn-cli --domain www.example.com --image-max-width 2560Every JPEG and PNG wider than the limit, in pixels, is scaled down to that width with its proportions kept. This changes the image files that are deployed: each keeps its name and format but is saved again, JPEGs at quality 85 and PNGs losslessly. Nothing in your pages changes, because no file is renamed.
- Nothing is enlarged. Images no wider than the limit are left exactly as they are.
- A file is never made larger. If the saved file isn’t smaller than the original, the original is kept.
- Photos stay upright. A photo’s rotation from the camera is applied before it’s measured and saved.
- Left as they are: animated PNGs, CMYK JPEGs, 16-bit PNGs, images over 40 megapixels, and images with a colour profile other than sRGB. GIF, SVG and every other kind of file are never touched.
ee-deploy lists each resized image with its size before and after, then the total saved. With --image-report, the report has a resize section with the same details.
Width hints in your pages keep the original width. A srcset width (photo.jpg 4000w), og:image:width and og:image:height, and structured-data dimensions still state the size before resizing. Browsers lay out images by their CSS or their width and height attributes, which keep the right proportions, so most sites look the same. Choose a limit at or above the widest srcset width your generator writes.
--image-max-width is a flag, with no ee.jsonc setting. In the Astro integration it’s deploy.imageMaxWidth, and in the GitHub Action the image-max-width input.
Which version you need
Section titled “Which version you need”@evolving-edge/ee-cdn-cli |
Packaging tool | |
|---|---|---|
Converting (--images) |
0.4.0 | Published on or after 2026-10-23 |
Resizing (--image-max-width) |
0.4.0 | Published on or after 2026-10-24 |
ee-deploy uses the latest packaging tool unless you pin a version. If the tool it would use is older than an option needs, it stops before packaging and says what to do: unpin it, pin a newer version, or update the checksum in your lockfile. The same check runs when your ee.jsonc turns conversion on.
Content hashes
Section titled “Content hashes”Converted and resized images are part of what’s published, so the content hash is of the changed files. The same site with the same settings gives the same files, and the same hash, on every computer and in CI, whichever operating system runs the deploy.
