NO.151
Same JPEG, 144 KB lighter: Chrome 155 decodes JPEG XL
Chrome now ships JPEG XL decoding. We ran this issue's own print through four formats and repacked a JPEG without changing one pixel.
What would your hero images weigh?
Range from Chrome's stated 30 to 50 percent
Add up the JPEGs on one template. A product page with eight photos often lands between one and three megabytes.
1,200 to 1,680KB as JPEG XL
That range is the vendor's claim for lossy encoding. Your own photographs decide where in it you land.
The third bar uses one measurement from this issue: a lossless JPEG to JPEG XL repack that came out 20.5 percent smaller and decodes back to the identical JPEG. Claim from Chrome for Developers.
Today's art direction
The Savings Proof
An image savings calculator on a vivid olive ground, with a linocut proof and a specimen sheet doing the arithmetic.
- range bar
- specimen sheet
- proof print
- block tile
- stencil numeral
- measured ledger
- format badge
A web-native calculator landing page of the kind an image CDN or a performance consultant sells from. The page states its numbers as ranges and measurements, never as a single promised figure, and the background is a tile of nested blocks drawn the way a variable-block codec splits a square.
Saira Stencil One sets the display like a crate stamp against a plain Figtree body, with Red Hat Mono for every measured value.
The lead, Chrome 155
JPEG XL decodes in Chrome without a flag
Chrome is shipping JPEG XL decoding from Chrome 155, and the team pitches the format on 30 to 50 percent better compression than JPEG, lossless compression, built-in HDR, and lossless JPEG transcoding. The decoder is jxl-rs, a memory-safe Rust implementation, and the decision traces to repeated requests through the Interop process.
The post does not crown a winner. It tells you to try both AVIF and JPEG XL, and expects JXL to help most with high-fidelity or lossless work on photographs, and wherever fine-grained progressive loading matters.
- Ships in
- Chrome 155Decoding on by default, no flag.
- Claimed saving
- 30 to 50%Versus JPEG, per the Chrome post.
- Decoder
- jxl-rsPure Rust, SIMD without unsafe code.
Specimen sheet: one crop, equal quality, four weights
512 px crop, smallest file scoring 80 on ssimulacra2. Tiles at 2x; bars share one scale, JPEG at full width.

JPEG 110.7 KB
4:4:4, quality 3 of 31
WebP 95.3 KB
lossy, q86, 14 percent under JPEG
AVIF 77.1 KB
q74, speed 4, 30 percent under
JPEG XL 82.0 KB
distance 1.1, effort 7, 26 percent under
Push the bar to 90 and the field narrows: AVIF needed 150.0 KB, JPEG XL 156.6 KB, and neither JPEG nor lossy WebP reached the score at any setting we tried.
Where AVIF won: on this print AVIF edged JXL on bytes at both bars. That is exactly why Chrome's own advice is to test both on your real images.
Nothing gets shot again or exported again. The old JPEG goes in, and the old JPEG can come back out.
On lossless transcoding, measured below
Technique, the repack
Shrink the JPEG library you already have
Lossless JPEG transcoding is the feature that changes a migration plan. cjxl takes an existing JPEG and stores the same coefficients more compactly, and djxl hands the original file back, byte for byte. Nothing is re-encoded, so nothing degrades.
<picture>
<source srcset="hero.jxl" type="image/jxl">
<img src="hero.jpg" width="1536" height="1024" alt="...">
</picture>
- Input
- This issue's print saved as a JPEG, 704,528 bytes.
- Repacked
- 560,166 bytes as JPEG XL with default settings, 20.5 percent smaller.
- Round trip
- Decoded back to a JPEG identical to the input, checked with cmp.
- Serve it
- Put the JXL first in a picture element and keep the JPEG as the fallback.
Workflow, Next.js 16.4
New Next.js apps start with Cache Components on
Next.js 16.4 makes Cache Components the recommended model for every app and turns it on by default in create-next-app. You mark parts of a page with use cache, so a personalised shell and cached product grids can share one route.
For older codebases, a new next upgrade --agent command feeds a coding agent version-specific upgrade guidance, backed by Skills for the refactors. The release also lists smaller production bundles and React 19.3.
- New apps
- On by defaultcreate-next-app turns on Cache Components.
- Old apps
- --agentUpgrade guidance a coding agent can follow.
Borrow this pattern
Show the saving as a range, beside your own measurement
Any savings calculator, for bandwidth, energy, or fees, is tempted to print one big number. Draw the vendor's claim as a band with a floor and a ceiling, then drop a single tick for the figure you measured yourself. The reader sees the promise and the evidence on the same scale.
- Where
- Pricing calculators, migration estimates, energy or fee savings pages.
- Build
- One track per row, a filled bar for today, an absolutely placed band for the claim, a 2px tick for the measurement.
- Honesty
- Name the source of the band in the caption, and label the tick with what was measured and how many times.
Prompt Lab
Build the savings proof page
Build a calculator landing page for an image optimisation service that sells smaller page weight. The page proves its claim with ranges and measurements, never one promised number. 1. Ground: a vivid mid olive (#AAA82B) across the whole page, overlaid with a 96px SVG tile of nested squares (one 48px block split into 24px and 12px blocks) in ink at 8 percent opacity. Panels sit on top in cream (#F2EEDC) or ink (#1B1C10). One accent, crimson (#B3261E), used only for a measured tick and the winning format's weight bar. 2. Type: Saira Stencil One for the hero numeral, h1, and h2s; Figtree for body at 19px, line-height 1.68; Red Hat Mono for every number, unit, and label. 3. Hero: the masthead is a stencil issue numeral folded into the hero over a 2px ink rule, with a one-sentence byline right-aligned on the same baseline. Then a 15ch stencil headline, a deck, and a full-width proof print on a cream mat. Serve it through a picture element (JXL source, WebP or JPEG fallback) and print in the caption which format the browser actually drew. 4. Calculator: a full-width ink panel. Left, a labelled number input with a KB unit tag. Right, the result as a range in display type, then three rows of horizontal bars on one shared scale: today (full cream bar), the claim (an olive band from the floor to the ceiling), and your own measurement (a 2px crimson tick). Caption names the claim's source. 5. Sections open with a 2px ink rule and an uppercase mono kicker above the h2. Body text stays in a 700px column on the left; specimen sheets and the calculator break out to the full container. 6. Specimen sheet: a cream panel of four square tiles, one per format, each captioned with the format in stencil, its byte size in mono, a thin weight bar on a shared scale, and the encoder settings. Use real measurements only. 7. Guardrails: body at least 18px with line-height at least 1.6, AA contrast on every surface (no crimson text on olive), no fake text inside images, no neon, no glow, no gradients, radius 4 to 6px, one soft shadow on the hero proof only, hover and focus states at about 150ms, and a reduced-motion guard. On mobile the calculator stacks and the specimen tiles go two by two.
Works in Claude Code, Beaver Builder AI, v0, Lovable, Framer, and Webflow's AI site builder.
Field note
Measure before you migrate
The repack is free money for an archive of JPEGs; the new-encode choice between AVIF and JXL is a test you run on your own photographs.
Credits
Sources
- Shipping JPEG XL in ChromeChrome for Developers, Luca Versari, Moritz Firsching, Philip Jägenstedt, October 6, 2026
- Next.js 16.4Next.js blog, October 6, 2026
- Next.js v16.4.0 release notesGitHub, October 7, 2026
- libjxl, the JPEG XL reference tools (cjxl, djxl, ssimulacra2)GitHub, used for this issue's measurements