Writing · 2026-04-27

Lossless JPEG to JPEG XL transcoding, explained

Re-encode a JPEG as JXL, save ~20% storage, decode back to a pixel-perfect JPEG later. How it works and when to use it.

Most image compression has a one-way door. You pick a quality setting, you save the file, and the original detail is gone forever. Lossless JPEG to JPEG XL transcoding breaks that rule.

What lossless transcoding actually means

A JPEG file is not just pixel data. It is the result of a specific encoding pipeline: DCT transforms, quantization tables, Huffman coding. JPEG XL’s libjxl can read every byte of a JPEG, re-encode the same coefficients using better entropy coding, and write a smaller JXL file that, when decoded, produces a bit-identical JPEG.

You save space. You keep the file. You can restore the original any time.

This is a different category of compression from what most people picture. When you “re-save a JPEG at lower quality,” you decompress the original to pixels, then compress those pixels with a different quality setting, then write a new JPEG. The math runs once for nothing and again with information loss. Lossless transcoding skips the round trip entirely. It works on the JPEG bitstream itself, not on the decoded image.

Why JPEG XL specifically

JPEG XL was designed with this trick in mind. The format spec includes a JPEG recompression mode that stores the JPEG’s coefficients in a packing that the original JPEG decoder cannot read, but a JXL decoder can. The numbers your JPEG was already carrying around are still there. They are just packed more efficiently.

Other modern formats cannot do this. AVIF is built on the AV1 video codec, which uses a different transform. WebP uses VP8 prediction. To get a JPEG into either of them, you have to decode it to pixels first, and at that point you have a new image, not a smaller copy of the old one. Re-encoding to AVIF will be smaller, but it is no longer the same file in any meaningful sense. The coefficients are gone.

JPEG XL is the only mainstream format that treats existing JPEGs as a first-class input.

What this gets you

For a typical camera JPEG, lossless transcoding produces a JXL file roughly 20 percent smaller. The libjxl maintainers publish this figure across mixed datasets and it tracks with what you will see in practice, though the exact ratio depends on the original JPEG’s quality setting and content.

You can store a 100 GB photo library in roughly 80 GB without losing a pixel. You can ship JPEGs as JXL over a slower connection. Your archival workflow stops being “do I keep the original or the compressed version” and becomes “store the JXL, restore the JPEG on demand.”

That last property is the one most people underestimate. A traditional lossy re-encode is a one-way decision. A lossless JXL transcode is reversible. If you change your mind in five years, the JPEG is still in there, byte for byte.

What it doesn’t do

Three things to keep in mind.

First, it is not magic compression. If your goal is a 200 KB file for a web page, lossless transcoding is the wrong tool. Use lossy JXL, AVIF, or jpegli at quality 80. Lossless transcode preserves the JPEG’s existing quality level. If the JPEG was already small and lossy, the JXL will be small and lossy in the same places.

Second, it is JPEG-specific. You cannot losslessly transcode a PNG to JXL with the same kind of guarantee. PNG can be encoded as lossless JXL, but that is a different mode and the math works differently. The “bit-identical restore” property is a JPEG-only feature of the format.

Third, you need a JXL decoder to read the file. Safari 17 on macOS Sonoma and later ships one. iOS 17 ships one. Chrome and Firefox have not enabled JXL by default as of 2026. For long-term archival this matters less. The format is stable, the spec is final, decoders exist as small libraries. But you cannot expect a random recipient to open a JXL file the way they would open a JPEG.

When to reach for it

A short list.

You shoot photos and you want a smaller archive without re-converting your camera files. Transcode the JPEGs the camera writes, store the JXLs, keep the originals around if you want a double safety net, or delete them once you trust the format.

You ship a large library and storage cost is real. The savings stack across thousands of files.

You hand a client a project archive and want the smallest possible bundle that they can fully recover later. Ship the JXLs with a one-line note about how to decode them.

You are building a photo workflow where files move through several stages and you want one of those stages to be smaller without committing to a generational loss.

When to skip it

You want web delivery on every browser today. Use AVIF.

Your image started as a PNG, RAW, or screenshot. Use lossless JXL directly from the source, not transcode.

Your JPEGs were already quality 90 from a camera and the storage savings will be modest. The space gain might not justify the workflow change.

How Sqz does it

Sqz wraps libjxl’s JPEG recompression path with a Mac-native batch interface. You drag a folder of JPEGs in, pick “Lossless JPEG to JXL,” and the app processes them in parallel. The original JPEGs are not modified. The JXL files appear next to them. To restore a JPEG from one of those JXLs later, any JXL decoder that supports the recompression mode will give you back the original file, byte for byte.

This is the one thing Sqz does that no other Mac App Store app does today. ImageOptim has not added JXL support. Squash 3 supports AVIF and WebP but not JXL recompression. Direct-download tools like Zipic include JXL, but they live outside the App Store, so updates, sandboxing, and trust are on you to verify.

If you want the trick available on macOS through Apple’s distribution, this is the path.

← All writing
#jxl #lossless #archival