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 type attribute 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.