AVIF (AV1 Image File Format) is an image format that stores pictures compressed with the AV1 video codec inside a HEIF container, and usually produces smaller files than JPEG or WebP at similar visual quality.
It is supported by current versions of Chrome, Edge, Firefox and Safari. This entry is part of the screenshot glossary. Its closest relative is WebP, which does the same job with an older video codec (VP8).
What it means in plain terms
AVIF takes the techniques a modern video codec uses to compress one frame and applies them to a still image. It handles flat colour, gradients and sharp edges well, supports transparency, and can store HDR and wide colour. The cost is time: encoding AVIF takes noticeably longer than encoding JPEG or WebP.
Measured: one screenshot, four formats
We captured two 1200×630 pages with headless Chrome and encoded each PNG with sharp: a text page (example.com) and a gradient social card made from HTML.
| Format and setting | Text page | Gradient card |
|---|---|---|
| PNG (Chrome output, lossless) | 68,350 bytes | 351,868 bytes |
| JPEG, quality 80, mozjpeg | 34,428 bytes | 35,726 bytes |
| WebP, quality 80 | 29,698 bytes | 27,198 bytes |
| AVIF, quality 50, effort 4 | 19,523 bytes | 11,947 bytes |
| Encode time, AVIF vs WebP | about 90 ms vs 35 ms | about 90 ms vs 40 ms |
Method: Node 22.18.0, sharp 0.35.5 (libvips 8.18.7, libaom 3.15.1) on an Apple Silicon Mac, 2026-10-15. File sizes were identical across two runs; the times are rounded from two runs and only show the ratio. Quality numbers are not comparable across formats: AVIF quality 50 and WebP quality 80 are both common "good enough" settings, so judge the outputs by eye on your own content before you fix a value.
What the table shows: AVIF gave the smallest file on both pages, and its lead was much bigger on the gradient card, where PNG is at its worst. On a text page, the gain over WebP is real but smaller.
How it works technically
An AVIF encoder splits the image into blocks, predicts each block from its neighbours, and stores only the corrected difference after a frequency transform, just as AV1 does for a video frame. Larger and more flexible block sizes and better prediction modes than JPEG's fixed 8×8 blocks explain most of the savings, especially on smooth areas. The result goes into an ISOBMFF/HEIF container, the same family as MP4. That is why file reports an AVIF as ISO Media, AVIF Image.
How to get AVIF from a headless browser
Chrome's screenshot command does not encode AVIF. When we called page.screenshot({ type: 'avif' }) in Puppeteer, Chrome answered Protocol error (Page.captureScreenshot): Invalid image format. Playwright's screenshot API has no AVIF option either. The answer in both tools is the same: capture a lossless PNG, then encode once.
Puppeteer
import puppeteer from 'puppeteer'; import sharp from 'sharp'; const browser = await puppeteer.launch(); try { const page = await browser.newPage(); await page.setViewport({ width: 1200, height: 630 }); await page.goto('https://example.com', { waitUntil: 'load' }); const png = await page.screenshot({ type: 'png' }); // lossless source, encode once await sharp(png).avif({ quality: 50, effort: 4 }).toFile('example.avif'); console.log('wrote example.avif'); } finally { await browser.close(); }
Playwright
import { chromium } from 'playwright'; import sharp from 'sharp'; const browser = await chromium.launch(); try { const page = await browser.newPage({ viewport: { width: 1200, height: 630 } }); await page.goto('https://example.com'); const png = await page.screenshot(); // lossless PNG by default await sharp(png).avif({ quality: 50 }).toFile('example-pw.avif'); console.log('wrote example-pw.avif'); } finally { await browser.close(); }
Tested on 2026-10-15 with Node 22.18.0, [email protected] (Chrome 148, run with headless: 'shell'), [email protected] and [email protected].
RenderScreenshot
The documented output formats are png, jpeg, webp and pdf; AVIF is not one of them. Request a PNG and convert it on your side with the same sharp call:
import { Client, TakeOptions } from 'renderscreenshot'; import sharp from 'sharp'; const client = new Client(process.env.RS_API_KEY); const png = await client.take( TakeOptions.url('https://example.com').preset('og_card').format('png') ); await sharp(png).avif({ quality: 50 }).toFile('example.avif');
If you want a smaller file without a conversion step, webp with quality is available directly. See output options. This SDK snippet was not run for this page.
Serve it with a fallback
<picture> <source srcset="/shots/home.avif" type="image/avif"> <source srcset="/shots/home.webp" type="image/webp"> <img src="/shots/home.png" width="1200" height="630" alt="Home page of example.com"> </picture>
Older browsers skip sources they cannot decode. Send the correct MIME type, image/avif, from your server or CDN.
Common mistakes
- Converting from JPEG. Encoding a lossy file again stacks artefacts. Start from PNG.
- AVIF for
og:image. Use PNG or JPEG for social cards. - Encoding on every request. At these encode times, convert once and cache the result.
- Maximum effort by default. Higher
effortvalues in sharp shrink files a little and slow encoding a lot. - Comparing quality numbers across formats. Compare file size at the same visual quality instead.
Related terms
For a format decision across PNG, JPEG and WebP captures, read PNG vs JPEG vs WebP for screenshots. To get PNG captures to convert, create a free account.