Multi-format Images
Letting the browser pick between AVIF, WebP, and JPEG with a single <picture> element.
Live Implementation
Open dev tools → Network tab, reload, and check which file actually downloaded. In a modern browser it'll be the AVIF; force-disable AVIF/WebP support and it falls back to JPEG, all from one `<picture>` element:

How It Works
The Responsive Images demo covers serving different sizes of the same file. This one covers a different axis: different formats. AVIF is smaller than WebP, which is usually smaller than JPEG, but browser support still varies, so you don’t want to just serve AVIF and hope.
Ask @11ty/eleventy-img for more than one format and it stops generating a plain <img> and gives you a real <picture> element instead:
const metadata = await Image(src, {
widths: [400, 800, 1200],
formats: ["avif", "webp", "jpeg"],
outputDir: "public/assets/images/optimized/",
urlPath: "/assets/images/optimized/",
});
return Image.generateHTML(metadata, { alt, sizes, loading: "lazy", decoding: "async" }); That produces one <source> per format, each with its own srcset of widths, in the order listed, plus a plain <img> as the final fallback. The browser walks the <source> list top to bottom and uses the first format it actually supports, so a browser that understands AVIF never even requests the WebP or JPEG versions.
The source image here is a small gradient generated specifically for this demo (there’s no royalty-free photo bundled with the repo), which is enough to actually show a size difference between formats. A flat-color icon compresses about the same in every format, so it wouldn’t prove much.
Folder Structure
src/_data/multiFormatImageDemo.js ← calls Image() with three formats
src/assets/images/demos/gradient-source.jpg
src/_includes/demo-live/multi-format-images.njk Important Files
src/_data/multiFormatImageDemo.js
import Image from "@11ty/eleventy-img";
export default async function () {
const metadata = await Image("src/assets/images/demos/gradient-source.jpg", {
widths: [400, 800, 1200],
formats: ["avif", "webp", "jpeg"],
outputDir: "public/assets/images/optimized/",
urlPath: "/assets/images/optimized/",
});
return Image.generateHTML(metadata, {
alt: "A generated gradient image used to compare AVIF, WebP, and JPEG output",
sizes: "(min-width: 40rem) 30rem, 90vw",
loading: "lazy",
decoding: "async",
});
} Notes
- Format order in the
formatsarray matters. List your most-preferred (usually AVIF) first, since that’s the one capable browsers will pick. - Just like the other Responsive Images demo, this is precomputed once through global data rather than called inline, since it only ever needs to process this one source file.
- AVIF encoding is noticeably slower than WebP or JPEG at build time. On a site with hundreds of images, that’s worth knowing before you turn it on for everything.