Guide · Frontend
JPEG XL Chrome Support Explained: When to Use It Over AVIF or WebP
19 min readUpdated By Saket Bhatnagar
Researched and drafted with AI, reviewed and edited by Saket Bhatnagar.
In short
- JPEG XL is a newer image format. JPEG XL Chrome support is here: Chrome 155, stable since 6 October 2026, decodes (unpacks into pixels) .jxl files with no setting to switch on.
- JPEG XL competes with AVIF and WebP, two other modern web formats. In web developer Jake Archibald's 15 October 2026 tests, AVIF made smaller lossy files (which drop detail the eye rarely notices) for most photos.
- JPEG XL clearly won his lossless tests (every pixel kept). It also shrank existing JPEGs 9 to 20 percent with no new quality loss, a trick called lossless JPEG recompression.
- As of 19 October 2026, Firefox 158 and Safari 17 or later decode it too. Serve .jxl inside a picture element, an HTML tag listing several versions of one image, so other browsers get a JPEG.
- Beginners can stop after the section on fallbacks. Engineers then get a byte-for-byte cjxl and djxl check, our libjxl 0.12.0 measurements, and the lossless decode-speed cost debated before launch.
What goes wrong when you switch every product photo to a new format?
Images break, lose quality or end up bigger than they need to be when a team swaps every file to a new format in one go. JPEG XL Chrome support arrived in Chrome 155 on 6 October 2026, and that news tempts teams to convert everything to .jxl overnight.
A browser that cannot decode the new format shows a broken image unless the page offers another version. Turning a JPEG back into pixels and saving them as a new lossy file adds a second round of quality loss. And for screenshots and banners with text, AVIF often makes smaller files.
Picture a common setup. An online jewellery shop holds 40,000 product photos saved as JPEGs years ago, and most original camera files are gone. Its CDN (content delivery network, the servers that deliver files from near each visitor) bill is about ₹70,000 a month. The setup is made up, but the problem is real.
A frontend engineer on the team reads the Chrome 155 news and proposes converting the whole catalogue that weekend. The team lead asks for one page first: what to convert, what to skip and what other visitors will see. This guide builds that page.
Which words do you need before comparing image formats?
- Decoder: the code that unpacks an image file into pixels. A browser needs one for each format it shows.
- Encoder: the tool that writes the file. Its effort setting is how long it searches for a smaller file.
- Transcode vs re-encode: transcoding repacks a JPEG's existing data; re-encoding decodes to pixels and compresses them again, losing more detail.
- Progressive decoding: showing a rough image while the rest of the file still downloads.
- MIME type: the label naming a file's format, such as image/jxl, image/avif or image/webp. Servers send it in the content-type header.
Is JPEG XL Chrome support on by default in Chrome 155?
Yes. Chrome 155 decodes .jxl images without a flag (a hidden setting you switch on by hand), and version 155 reached stable on 6 October 2026. Chrome's 155 release notes describe decoding for image/jxl using jxl-rs.
The Intent to Ship, Chrome's public notice that a feature is ready, was posted on blink-dev, Chrome's public developer mailing list, on 24 August 2026. Its rollout plan says the feature will ship enabled for all users. It got three LGTM ("looks good to me") approvals that day.
The same notice names a Finch feature, JXLImageFormat. Finch is the system Chrome uses to switch features on or off from a server, and Chrome's docs say it can remotely disable problematic features. So treat "enabled for all users" as the plan, not a guarantee.
The Chrome team's launch post says JPEG XL offers "30-50% better compression than JPEG". That is the team's claim, not a figure this guide tested. It also lists lossless compression, HDR (high dynamic range: brighter highlights and deeper shadows) and lossless JPEG transcoding.
Why did Chrome drop JPEG XL in 2022 and bring it back?
Chrome tried JPEG XL once before, behind a feature flag that was off by default, then removed it. That attempt began with a blink-dev Intent to Prototype, Chrome's notice that work on a feature is starting, on 30 March 2021.
On 11 November 2022, Chrome announced it would "stop Chrome's JPEG XL experiment and remove the code". The post listed questions such as compression across many images, decoder speed, encoding cost and support in other browsers and operating systems.
The 2026 launch post says the decision to ship was based on consistent feedback and requests from web developers. JPEG XL was a popular proposal in the Interop process, the yearly effort where browser makers pick features to make work alike, in 2026 and several years before.
How does lossless JPEG recompression to JPEG XL work?
JPEG XL can losslessly transcode an existing JPEG: it stores the JPEG's image data more compactly in a .jxl file, plus reconstruction data. Nothing new is thrown away, and MDN notes that the original JPEG file can be reconstructed.
Think of repacking a suitcase: the same clothes come out, they just take less space. Re-encoding is different. Decoding a JPEG to pixels and saving them as a new lossy file loses detail again, like photocopying a photocopy.
Where the picture breaks: anyone can open a suitcase, but only software with a JPEG XL decoder can open a .jxl. That is why the original JPEG stays on the server as the fallback.
Jake Archibald's tests found lossless transcoding made JPEGs 9 to 20 percent smaller. The saving grew with image width, from about 9 percent at 400 pixels wide to about 20 percent at 4,900 pixels.
Repacking the shop's old JPEGs
Drag to exploreNotice the fallback arrow: the original JPEG is never deleted, so a browser without JPEG XL still gets it.
Diagram connections:
- Old JPEG archive to Lossless transcode job (read each file)
- Lossless transcode job to .jxl copies (write smaller copy)
- .jxl copies to Browser with JPEG XL (served as image/jxl)
- Old JPEG archive to Visitor without JPEG XL (fallback, untouched)
- Old JPEG archive: 40,000 product photos, masters mostly lost
- Lossless transcode job: Repacks each JPEG; no new quality loss
- .jxl copies: About 9-20% smaller in Jake Archibald's tests
- Browser with JPEG XL: Chrome 155+, Firefox 158+, Safari 17+ get the .jxl
- Visitor without JPEG XL: Gets the original JPEG from the img tag
The engineer estimates the monthly saving. Every input except the 9 to 20 percent range is made up, and GB here means decimal gigabytes (1,000,000 kB).
avg_jpeg_kb = 380 # made up: average archive photo, in kB
monthly_downloads = 30_000_000 # made up: image downloads per month
jxl_share = 0.6 # made up: share of downloads from browsers that pick the .jxl
rupees_per_gb = 6 # made up: CDN price per GB
for saving in (0.09, 0.20): # range from Jake Archibald's JPEG transcoding tests
gb_saved = monthly_downloads * jxl_share * avg_jpeg_kb * saving / 1_000_000
rupees = gb_saved * rupees_per_gb
print(f"{saving:.0%} smaller: {gb_saved:,.0f} GB and about Rs {rupees:,.0f} saved a month")The script prints 616 GB and about Rs 3,694 (Rs means rupees) at 9 percent, and 1,368 GB and about Rs 8,208 at 20 percent (made up). Useful, but only a modest slice of a ₹70,000 bill, and the engineer says so.
Pause and predict: if JPEG XL repacks old JPEGs this well, will it also make the smallest new lossy photos? The next table answers with measurements.
JPEG XL vs AVIF vs WebP: which should you use for each image?
For most new lossy images, Jake Archibald's October 2026 tests favour AVIF. JPEG XL won for lossless images and old JPEGs. WebP stays a widely supported fallback; MDN says major browsers broadly support it.
His default is "AVIF 4:4:4, with the highest effort level I can be bothered with". Here 4:4:4 means full colour detail is kept rather than shared between neighbouring pixels.
The Chrome team says to try both AVIF and JPEG XL. It expects JPEG XL to help most with high-fidelity or lossless compression, especially of photographs.
| Kind of image | Smaller file in his tests | Rough gap he measured | The shop's choice (made up) |
|---|---|---|---|
| Lossy photos | AVIF, almost always | Best default JPEG XL typically 15-25% larger; 6-20% at max effort | AVIF first, JPEG XL tried on outliers |
| Screenshots and illustrations | AVIF, by a lot | JPEG XL 30-90% larger at default | AVIF for banners and size charts |
| Images with transparency | AVIF | JPEG XL at least 31% larger at default | AVIF for cut-out jewellery shots |
| Lossless photos | JPEG XL, clearly | Lossless WebP 9-17% larger; lossless AVIF 30-120% larger | JPEG XL with a WebP fallback |
| Existing JPEGs | JPEG XL transcode | 9-20% smaller than the JPEG, no new loss | Repack the 40,000-photo archive |
| HDR photos | Depends on the quality metric | No browser decodes JPEG XL gain maps (extra HDR data), he notes | Not used yet |
Lossless gaps depend on the images. On four sample photos with libjxl 0.12.0, our lossless WebP files were 0 to 8 percent larger than JPEG XL, a smaller gap than his.
Jake also found JPEG XL typically takes 2 to 3 times as long as AVIF to decode at medium quality. The gap narrowed at very high quality.
The engineer turns the table into a rule for the upload pipeline, returning picture sources best first.
def pick_sources(photo):
"""Return the picture sources for one image, best first."""
if photo["origin"] == "old_jpeg":
# Lossless repack: same JPEG data, smaller file, original JPEG as fallback
return ["jxl", "jpeg"]
if photo["needs_exact_pixels"]:
return ["jxl", "webp", "png"]
# New lossy photos, banners and cut-outs: AVIF first, as public tests suggest
return ["avif", "webp", "jpeg"]
catalogue = [
{"name": "jhumka_0412", "origin": "old_jpeg", "needs_exact_pixels": False},
{"name": "hallmark_scan", "origin": "scanner", "needs_exact_pixels": True},
{"name": "diwali_banner", "origin": "design", "needs_exact_pixels": False},
]
for photo in catalogue:
print(photo["name"], "->", pick_sources(photo))It prints jxl then jpeg for the old jhumka (earring) photo, jxl, webp and png for the hallmark scan, and avif, webp and jpeg for the banner. The team keeps lossless rare, since Jake found lossy AVIF handles screenshots well.
How do you serve JPEG XL safely with fallbacks for other browsers?
Put each format in its own source line inside a picture element, best first, and end with a plain img tag. MDN says a browser compares each source's MIME type with the types it can display, and skips unsupported ones without asking the server.
MDN advises giving JPEG XL an alternative such as AVIF, WebP or JPEG. As of 19 October 2026, MDN lists Chrome 155, Firefox 158 and Safari 17, but still calls support not yet universal.
So what will other visitors see? Shoppers on current Chrome, Firefox and Safari get the .jxl. Older versions, and browsers such as Samsung Internet that caniuse marks unsupported, get the JPEG.
The order of sources
Order sets priority. For repacked archive photos, the team lists the .jxl source first and keeps the original JPEG in the img tag. For new lossy photos it lists AVIF, then WebP, then JPEG.
How a browser picks from an archive photo's picture element
Drag to exploreFollow the No arrow: a browser without JPEG XL never fetches the .jxl and still gets the original JPEG.
Diagram connections:
- Product page loads to Decodes image/jxl? (read picture element)
- Decodes image/jxl? to Fetch necklace.jxl (Yes)
- Decodes image/jxl? to Fetch necklace.jpg (No)
- Fetch necklace.jxl to Photo shown (decode and paint)
- Fetch necklace.jpg to Photo shown (decode and paint)
- Product page loads: Shopper opens a necklace page
- Decodes image/jxl?: First source line: the repacked .jxl
- Fetch necklace.jxl: About 9-20% fewer bytes in public tests
- Fetch necklace.jpg: The img tag fallback, the untouched original
- Photo shown: Same picture; tiny rounding between decoders
Rolling out without surprises
- Start with one category, such as earrings, and compare load times.
- Check that your CDN sends .jxl files with the image/jxl content type, using the command below.
- Keep the original JPEGs: they are your fallback and your undo button.
- Watch real-user timings on low-end Android phones.
curl -sI "$IMAGE_URL" | grep -i content-type
# expected: content-type: image/jxlSet IMAGE_URL to one of your .jxl files. The header name's capitalisation can vary. If the value shows something else, such as application/octet-stream, fix the server's type mapping before rollout.
If you are new to image formats, you can stop here. The sections below are for engineers who will run the conversion and own its cost.
How do you check that a JPEG XL transcode is really lossless?
Rebuild the JPEG from the .jxl and compare the two files byte for byte. cjxl is the JPEG XL encoder and djxl the decoder from libjxl, the reference library.
cjxl photo.jpg photo.jxl # JPEG input: lossless transcode by default
djxl photo.jxl restored.jpg # .jpg output: rebuild the original file
ls -l photo.jpg photo.jxl restored.jpg
cmp photo.jpg restored.jpg && echo identicalWhat just happened? In version 0.7.0, cjxl's log says "lossless transcode" and "JPEG reconstruction data". ls should show photo.jpg and restored.jpg with the same size in bytes. cmp prints nothing when the files match, so the last line is identical.
We ran these commands with cjxl and djxl 0.7.0, the Ubuntu 24.04 package. The 0.11.2 manual pages document the same defaults: JPEG input is transcoded losslessly, and a .jpg output rebuilds the exact original.
What we measured with libjxl 0.12.0
Using libjxl 0.12.0, the version Jake tested, we transcoded 39 JPEGs made from sample photos 451 to 1,411 pixels wide. Every one came back byte-identical. Savings ran from 8 to 18 percent.
How the JPEG was saved mattered most. Already-optimised progressive JPEGs (saved to load in passes, with tuned compression tables) saved only 8 to 11 percent, and less at higher JPEG quality. The other JPEGs, including three sample files used as shipped, saved 11 to 18 percent.
The pixel trap
A .jxl made from pixels cannot give the original JPEG back. In our 0.7.0 test, djxl wrote a brand-new JPEG instead: 102,615 bytes against the original 56,809, and not identical.
Displayed pixels can also differ slightly even after a true transcode. We decoded the same photo with libjxl and with libjpeg-turbo, a common JPEG decoder. The results differed by under one level out of 255 on average, and by up to 22 at single points. The file is identical; the decoders' maths differs slightly.
How does Chrome's Rust decoder, jxl-rs, make JPEG XL safer?
jxl-rs is a JPEG XL decoder written in Rust, a language whose safe subset rules out whole classes of memory bugs. Chrome's post calls image decoders "one of the most critical and targeted attack surfaces" in a modern browser.
A decoder reads bytes from any website, including hostile ones. Chrome's post says decoders written in memory-unsafe languages like C++ have been prone to out-of-bounds reads, heap overflows and use-after-free bugs.
Safe Rust refuses to compile code that keeps a reference to memory after it is freed. It also stops the program, instead of reading stray memory, when code indexes past the end of an array.
How a .jxl image reaches the screen in Chrome 155
Drag to exploreNotice where the risky step sits: untrusted bytes become pixels in memory-safe Rust, inside the sandboxed renderer.
Diagram connections:
- Any website to Renderer process (image/jxl response)
- Renderer process to jxl-rs decoder (untrusted bytes)
- jxl-rs decoder to Decoded pixels (checked decode)
- Decoded pixels to Shopper's screen (paint)
- Any website: Sends .jxl bytes that may be crafted to attack
- Renderer process: Builds the page; the decoder runs inside it
- jxl-rs decoder: Rust code that turns bytes into pixels
- Decoded pixels: Plain colour values ready to paint
- Shopper's screen: Shows the necklace photo
The post says decoders run inside the renderer process, the part of Chrome that builds web pages, and calls sandboxing a secondary layer of defence. The sandbox is a walled-off process with few rights; memory-safe code is meant to stop the bug first.
For speed, the decoder uses SIMD instructions, which handle many pixels in one step. A Rust feature, target_feature_11, had to be stabilised so SIMD could be used without unsafe code, Rust's escape hatch from its checks.
The remaining unsafe operations sit in a SIMD layer called jxl_simd, restricted to what the post calls a small number of highly vetted locations. So when Chrome's release notes call jxl-rs a "memory-safe pure Rust decoder", that does not mean zero unsafe code.
The team checked the decoder with fuzzing, which feeds it huge numbers of broken files, and with AI review of the code. The post says it has "not found any memory safety bugs throughout the entire implementation history".
How does progressive decoding in JPEG XL compare with AVIF?
In Chrome, both can show a preview before the file finishes, but in Jake Archibald's test AVIF's early preview was more useful. The Chrome team still highlights JPEG XL for cases where fine-grained progressive decoding is preferred.
Jake found progressive JPEG XL "basically free at high effort" in file size. On one large photo, JPEG XL showed a very blurry preview after about 2 kB.
AVIF showed a recognisable preview after about 11.5 kB, and JPEG XL needed about 63 kB to match it. He worries a blurry preview can look like a finished but poor image.
As of his 15 October 2026 post, only Chrome supports progressive AVIF, and Chrome and Firefox show progressive JPEG XL. Safari shows a .jxl only once it has fully downloaded, as MDN also notes. The shop's zoom photos often load on patchy mobile data. So the team will test both formats in Chrome and in Safari on an iPhone, on a connection slowed on purpose.
How much does lossless JPEG XL cost to decode on phones?
More than lossless WebP, by a wide margin in some measurements. This was the main worry raised in the Intent to Ship thread before launch.
One participant measured lossless JPEG XL decoding about 15 to 20 times slower than lossless WebP, single-threaded, on a very large test image. He worried about battery, and noted cached images pay that cost on every page view.
Luca Versari, a co-author of Chrome's launch post, replied that the encoder's faster decoding setting "doubles decoding speed" without much change in size. He added that the huge test image would decode faster on several threads.
Philip Jägenstedt, another co-author of the post, called it a real risk but expected adoption to ramp up slowly. Our own run agrees on the direction. With libjxl 0.12.0 on one thread, lossless JPEG XL took 10 to 16 times as long as lossless WebP on two sample photos, 512 and 741 pixels wide. Faster decoding level 1 cut decode time by about a third, less than the doubling claimed, for 1 to 2 percent more bytes. Timings varied between runs.
Treat those as libjxl numbers, not Chrome numbers, because Chrome 155 decodes with jxl-rs. Transcoded JPEGs look different: Jake measured them slower than JPEG on small images, matching from about 1,000 pixels wide, and faster in Chrome at the largest sizes.
How do you explain JPEG XL support in a system design interview?
Treat it as a trade-off about formats, fallbacks and cost, using the jewellery shop as your example.
State the goal
Say what you optimise: bytes sent, time to a preview, quality or decode cost on cheap phones.
Split images by kind
Separate old JPEGs, new lossy photos, graphics and lossless assets.
Pick formats with evidence
Cite public tests: AVIF often wins lossy, JPEG XL wins lossless and JPEG repacking. Say you would test your own images.
Design the fallback chain
Use a picture element, best format first, with a JPEG or PNG img tag last.
Plan the pipeline
Encode in a background worker at upload, store variants in object storage, serve through the CDN with the right content type.
Measure and roll back
Roll out per category, watch real-user decode timings and keep originals to switch back.
Questions people ask
- Does Chrome 155 support JPEG XL by default?
- Yes, Chrome 155 decodes JPEG XL without a flag. The 24 August 2026 Intent to Ship says it will ship enabled for all users. It also names a Finch feature, JXLImageFormat, and Finch lets Chrome disable a feature remotely. So keep a fallback in every picture element.
- Is JPEG XL better than AVIF?
- It depends on the image. In Jake Archibald's 15 October 2026 tests, AVIF made smaller lossy files for most photos, screenshots and images with transparency, and decoded faster. JPEG XL clearly won for lossless images and for repacking existing JPEGs. The Chrome team suggests trying both, and Jake says to test with your own images.
- Can I get the original JPEG back from a JPEG XL file?
- Yes, if the .jxl was made by lossless JPEG transcoding. Run djxl with a .jpg output name and compare with cmp; in our test the rebuilt file was byte-identical. A .jxl made from decoded pixels cannot do this, and djxl then writes a new, different JPEG.
- Do Firefox and Safari support JPEG XL?
- Yes, in current versions. As of 19 October 2026, Firefox 158, released 13 October 2026, decodes JPEG XL by default, and Safari has since Safari 17. Safari shows a .jxl only after it fully downloads, with no progressive preview, and shows only the first frame of an animated .jxl. Older browsers and some others, such as Samsung Internet, still lack it, so always serve .jxl inside a picture element with a fallback.
- Does JPEG XL support animation and transparency?
- Yes. MDN lists both transparency and animation for the format. In the Intent to Ship thread, Luca Versari, a co-author of Chrome's launch post, said animated JPEG XL is enabled together with still images. Jake Archibald still advises against animated image formats in general.
- Will JPEG XL slow down pages on cheap phones?
- It can. Jake Archibald found lossy JPEG XL typically 2 to 3 times slower to decode than AVIF at medium quality. Lossless JPEG XL decoding also drew speed and battery concerns before launch. Measure real-user timings on low-end Android phones before rolling it out widely.
Sources and further reading
- Shipping JPEG XL in Chrome (Chrome for Developers blog, 6 October 2026)
- Intent to Ship: JPEG XL decoding support (image/jxl) in blink (blink-dev thread, 24 August 2026)
- Chrome 155 release notes, Multimedia section (Chrome Platform Status)
- Intent to Prototype: JPEG XL decoding support, 11 November 2022 removal message (blink-dev)
- Firefox 158 release notes for developers, JPEG XL enabled by default (MDN, 13 October 2026)
- JPEG XL browser support table (caniuse)
- What is a Chrome Finch experiment? (Chrome for Developers)
- The source element, usage notes on the type attribute (MDN)
- Image file type and format guide, JPEG XL and fallbacks sections (MDN)
- JPEG XL vs AVIF for web use-cases (Jake Archibald, 15 October 2026)
- cjxl manual page, libjxl-tools 0.11.2 (Debian)
- djxl manual page, libjxl-tools 0.11.2 (Debian)