How to Detect AVIF Support in JavaScript
Detecting client-side AVIF (AV1 Image File Format) compatibility in JavaScript allows web developers to dynamically serve high-compression images, update CSS backgrounds, or initialize optimized WebGL textures. Because AVIF offers superior compression compared to JPEG and WebP, verifying browser support before requesting assets ensures optimal performance without breaking visual elements for unsupported clients. This article outlines the most reliable, modern JavaScript techniques for detecting AVIF support.
The Asynchronous Image Decode Method
The most robust cross-browser technique involves loading an
ultra-small, 1x1-pixel AVIF image encoded as a base64 Data URI and
testing if the browser can successfully decode it using the
HTMLImageElement.decode() API.
async function checkAvifSupport() {
if (!window.createImageBitmap) return false;
const avifDataUri = 'data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAacGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAqaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlycGMgAAACqnBhc3MAAAAAAAAACGF2MUOBAAAAAAABAAAA';
const img = new Image();
img.src = avifDataUri;
try {
await img.decode();
return true;
} catch {
return false;
}
}
// Usage
checkAvifSupport().then((isSupported) => {
if (isSupported) {
document.documentElement.classList.add('avif');
} else {
document.documentElement.classList.add('no-avif');
}
});The decode() method returns a Promise that resolves when
the image has been fetched and decoded off the main thread, or rejects
if the format is unsupported or corrupted.
The createImageBitmap
Method
For background workers or scripts where DOM elements like
new Image() are unavailable, you can use the
createImageBitmap API paired with a binary Blob.
async function supportsAvifBitmap() {
const avifBinary = new Uint8Array([
0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70,
0x61, 0x76, 0x69, 0x66, 0x00, 0x00, 0x00, 0x00,
0x61, 0x76, 0x69, 0x66, 0x6d, 0x69, 0x66, 0x31,
0x6d, 0x69, 0x61, 0x66, 0x4d, 0x41, 0x31, 0x42
]);
const blob = new Blob([avifBinary], { type: 'image/avif' });
try {
const bitmap = await createImageBitmap(blob);
bitmap.close(); // Clean up memory
return true;
} catch {
return false;
}
}This method works inside Web Workers and Service Workers, making it ideal for client-side routing logic and resource pre-fetching.
Best Practices for Implementation
- Cache the Detection Result: Testing format
compatibility requires CPU cycles. Perform the test once per user
session and store the boolean value in memory,
sessionStorage, or a cookie. - Avoid Sync Hacks: AVIF cannot be reliably detected
via synchronous properties like
typeattribute checks on<source>elements, because support varies across underlying platform decoders and browser versions. Always use asynchronous decoding tests. - Prefer Native HTML Fallbacks: For static image
markup, rely on the
<picture>element with an AVIF<source>tag rather than JavaScript detection. Reserve JavaScript detection for dynamic Canvas rendering, WebGL textures, CSS class injection, or custom image-loading pipelines.