Image and audio decoder support
Browser support for a format depends on more than the codec: container, profile, bit depth, operating system and decoder build all matter. Use the matrices below to plan delivery, then test your own files.
Image delivery matrix
Section titled “Image delivery matrix”| Image format | Native web delivery status | Features needing independent tests |
|---|---|---|
| JPEG | Ordinary 8-bit baseline and progressive JPEG is broadly deployed. | Predictive lossless, higher precision, CMYK, color metadata and gain-map rendering. |
| PNG / APNG | Mature still and alpha support; APNG in current major browsers. | All animation frames, 16-bit handling, color management and third-edition HDR chunks. |
| GIF | Mature still and animation support. | Palette appearance, short-delay clamping, disposal and loop behavior. |
| WebP | Mature still, lossless, alpha and animation support in current major browsers. | Older embedded clients, hidden RGB samples, ICC/Exif/XMP preservation and animation compositing. |
| AVIF | Supported by current major browser families. Still and sequence milestones differ. | AV1 profile, precision and chroma; HDR, gain maps, grids, layered images and progressive painting. |
| JPEG XL | Safari 17+ (stills only), Chrome 155+, Firefox 158+ (stable due 2026-10-13). | Stable rollout, Safari animation limitation, progressive download behavior, high depth and HDR. |
| HEIC | Safari 17+ on supported Apple platform paths; narrower general web compatibility. | HEVC profile, auxiliary alpha and depth, collections, sequence timing and color. |
| JPEG 2000 | No current browser. Safari, the only browser that ever supported it, removed it in Safari 18.0. | JP2 versus JPX, HTJ2K and MJ2; component precision and signedness; alpha and color. |
| QOI | Plan an application decoder or a web-format derivative. Do not assume native HTML display. | Plugin or Wasm presence, straight-alpha handling and sample preservation. |
Sources: MDN image types, WebKit Safari 17 features and Safari 18.0 features. Native image support in an OS does not mean every browser on that OS supports the format.
JPEG XL
Section titled “JPEG XL”Chrome 155 (stable from 6 October 2026) decodes JPEG XL
by default using the Rust decoder jxl-rs. Firefox adds it in 158 (beta notes;
stable due 13 October 2026), also via jxl-rs. Safari has supported still JPEG XL images since
Safari 17 but not animation. Chromium derivatives and WebViews follow their own release schedules,
so keep a JPEG or AVIF fallback (<picture>) while older browsers are still in use.
List the formats in order of preference and end with a JPEG:
<picture> <source srcset="photo.jxl" type="image/jxl" /> <source srcset="photo.avif" type="image/avif" /> <source srcset="photo.webp" type="image/webp" /> <img src="photo.jpg" alt="Describe the actual photograph" /></picture>The browser picks a source by MIME type alone. It does not check HDR, alpha precision or animation for that particular file, so check each selected variant’s color and loading behavior.
Probe an actual image fixture
Section titled “Probe an actual image fixture”Images have no canPlayType() equivalent, so decode a small, representative fixture:
async function canDecodeImage(url) { const image = new Image(); image.src = url; try { await image.decode(); return image.naturalWidth > 0 && image.naturalHeight > 0; } catch { return false; }}
const stillJxlWorks = await canDecodeImage('/fixtures/still.jxl');A successful decode shows that one fixture decodes. It does not show that every animation frame, progressive pass or HDR value is correct. A failure can also come from CORS, a missing file or a network error. Canvas pixel inspection requires an origin-clean image.
Audio delivery matrix
Section titled “Audio delivery matrix”| Codec and carriage | Practical native browser path | Limits to validate |
|---|---|---|
| AAC-LC in MP4/M4A | Broad consumer browser and device delivery. | Chromium distribution and OS codec dependencies, multichannel layouts, priming and profile signaling. |
| HE-AAC / xHE-AAC / AAC-LD/ELD | Profile-specific platform and decoder paths. | AAC-LC support says nothing about these profiles. Codec configuration and effective sample rate matter. |
MP3 as audio/mpeg | Broad current-browser playback. | Rate generation, free-format restrictions, VBR seeking, delay and padding, and tags. |
| Opus in Ogg/WebM | Broad modern paths. Safari Ogg depends on newer OS support. | Exact carriage, pre-skip and end trimming, mapping family, multichannel and older Safari. |
| Vorbis in Ogg/WebM | Broad modern Chromium and Firefox; newer Safari Ogg paths. | OS version, chaining and seeking, and channel mapping. |
| FLAC in native FLAC | Broad modern native decode. | Native versus Ogg/MP4 carriage, bit depth, subset limits, high rates and channel placement. |
| ALAC in MP4/M4A | Apple and Safari native support. | Writer precision, channel order and non-Apple targets. |
| Speex in Ogg/RTP | Legacy endpoint or application-decoder path. | Do not assume browser-native playback. Rate, mode and packetization matter. |
| WavPack | Specialist player, or an application or Wasm decoder. | Float, DSD, hybrid correction and wrapper restoration are separate from native HTML support. |
| Dolby delivery | Codec, profile, OS and device dependent. | AC-3, E-AC-3, TrueHD and AC-4 differ. Atmos metadata, rendering and pass-through are separate. |
WebKit 18.4 added Ogg Opus and Vorbis on macOS Sequoia 15.4, iOS and iPadOS 18.4, and visionOS 2.4. An older supported macOS is therefore a different compatibility target. Older codec tables that say “CAF-only Opus” or “no Safari Vorbis” are out of date for these builds.
Check the MIME type and carriage
Section titled “Check the MIME type and carriage”const audio = document.createElement('audio');const probes = { aacLcMp4: 'audio/mp4; codecs="mp4a.40.2"', opusOgg: 'audio/ogg; codecs="opus"', opusWebm: 'audio/webm; codecs="opus"', vorbisOgg: 'audio/ogg; codecs="vorbis"', nativeFlac: 'audio/flac', mp3: 'audio/mpeg', eac3Mp4: 'audio/mp4; codecs="ec-3"',};for (const [name, type] of Object.entries(probes)) { console.log(name, audio.canPlayType(type));}canPlayType() returns
"", "maybe" or "probably". Neither positive result guarantees a particular profile, file, layout,
DRM path or audible output. Play a representative file, and test seeking and end-of-stream trimming.
Playback policy may also require user activation. <source> alternatives can cover unsupported types,
but a file that fails after selection needs fallback handling in your application.
For performance-sensitive playback, MediaCapabilities.decodingInfo()
returns supported, smooth and power-efficient estimates for a configuration. These estimates do not
identify every internal decoder or confirm hardware acceleration. WebRTC negotiation, MSE, encrypted
media and ordinary file playback each have their own constraints.
Check browser coding APIs independently
Section titled “Check browser coding APIs independently”async function supportsOpusApi(apiName) { const api = globalThis[apiName]; if (!api?.isConfigSupported) return false; try { const result = await api.isConfigSupported({ codec: 'opus', sampleRate: 48000, numberOfChannels: 2, }); return result.supported; } catch { return false; }}
console.log('WebCodecs decode', await supportsOpusApi('AudioDecoder'));console.log('WebCodecs encode', await supportsOpusApi('AudioEncoder'));WebCodecs codec support
varies by API and platform. WebCodecs works on encoded chunks. It does not demux an Ogg or MP4 file, and
it does not mux encoder output. AAC decoding can require the file’s codec description. MediaRecorder has
its own isTypeSupported() query. Receiving Opus over WebRTC does not mean an application can use these
other APIs.
Test on the target OS and browser builds with representative still, animated, HDR, stereo and surround, seeking and fallback files. For immersive audio, test the renderer and output route as well as the codec.