libjxl: the JPEG XL reference encoder and decoder, and when to use it
JPEG XL image format reference implementation
At a glance
- What is it?
- libjxl is the BSD-3-Clause reference implementation of JPEG XL, shipped as the cjxl encoder and djxl decoder. It is the right tool when you need spec-conformant .jxl files or lossless JPEG recompression, and the wrong one when you only need a drop-in JPEG encoder.
- Who is it for?
- Adopt libjxl if you need to write or read spec-conformant .jxl files, or if lossless JPEG recompression is the goal, because that is exactly what cjxl and djxl do by default. Do not adopt it expecting a frozen C API: the README states the library API and command line options are subject to change, so anything you link against libjxl needs to track releases.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What libjxl is for, and who ends up using it
JPEG XL was standardized in 2022 as ISO/IEC 18181. Part 1 specifies the core codestream, part 2 the file format, part 3 decoder conformance, and part 4 is the reference software. This repository is that part 4. So libjxl is not a product with a roadmap of its own; it is the working definition of what a correct JPEG XL encoder and decoder should do, maintained so that other implementations have something to be measured against.
The practical audience is narrow and specific. It is developers integrating JPEG XL into an application, because the repository ships example applications and plugins intended as a starting point for that. It is also anyone who needs to produce or inspect .jxl files directly, since the build produces two command line programs: cjxl for encoding and djxl for decoding. If you are a photographer looking for a converter, you are using libjxl indirectly, through an application that embeds it. The README points at a list of applications that support JPEG XL in doc/software_support.md, and that list, not this repository, is where you should look for a graphical tool.
The codestream, the container, and the JPEG recompression trick
The architecture follows the standard's split. A codestream layer handles the actual image data; a container layer handles metadata, multiple frames and the file-level framing. The repository layout mirrors this, with the library under lib/, the command line tools under tools/, example integrations under examples/, and format documentation under doc/, including doc/format_overview.md and doc/xl_overview.md.
The behaviour worth understanding before you touch the tools is what happens to JPEG input. According to the README, when cjxl is given a JPEG file its default behaviour is lossless recompression, and when djxl is given a .jxl file with a .jpg output extension its default behaviour is to reconstruct the original JPEG. That is a different operation from transcoding. The JPEG coefficients are stored in the JPEG XL container rather than re-encoded from pixels, and the decode path puts the original JPEG bytes back. It means a JPEG-heavy archive can be repacked without a generation loss, which is a use case ordinary image encoders cannot serve at all.
For everything else, the encoder exposes a rate control in two flavours. The --distance parameter is measured in just-noticeable difference units, where 0 is lossless and the README describes 0.5 to 3.0 as the most useful lossy range. The --quality parameter runs 0 to 100 and is described as roughly matching libjpeg. Those two scales are not the same scale, and picking between them is a real decision rather than a cosmetic one.
Installing libjxl on Ubuntu, Debian and macOS
On most Linux distributions the README says installation is a matter of the package manager. On Debian-based systems, the tools package brings in cjxl and djxl:
apt install libjxl-toolsAfter that, cjxl and djxl should both be on your path. Note that benchmark_xl, which the README mentions alongside the tools, lives in a separate package called libjxl-devtools, so a plain libjxl-tools install will not give it to you.
On macOS the README gives Homebrew as the route:
brew install jpeg-xlIf you are on Windows, or you want Debian and Ubuntu .deb packages directly rather than through a distribution repository, the README points at the releases page. Building from source is also documented, in BUILDING.md, and the repository carries CMakeLists.txt, BUILD.bazel and MODULE.bazel, so both CMake and Bazel builds are supported.
For a first real encode, the README's own example is the shortest path:
cjxl input.png output.jxlThat runs with default settings. To decode it back:
djxl input.jxl output.pngWhen you want to move away from defaults, --distance and --quality are the two knobs to try first, and --effort controls encode effort. The README directs you to cjxl --help for more settings, and to cjxl -v -v --help for the full list, which is worth knowing because the first help output is not the complete one.
The API is a moving target, and that is the main cost
The README contains an explicit warning: the library API, the command line options, and the tools in this repository are subject to change. What it promises instead is narrower and more useful. Files encoded with cjxl conform to the JPEG XL specification and can be decoded with current and future djxl decoders or the libjxl decoding library. So the file format is the stable contract, and the C API you would link against is not.
That distinction should drive your integration plan. If you shell out to cjxl and djxl, upgrades are cheap and the risk is mostly in flag changes. If you link libjxl into a long-lived binary, you own an API that the project has told you will move, and you will be reading the API documentation on readthedocs and the CHANGELOG rather than assuming compatibility.
The second constraint is security. The README carries a highlighted note recommending an update to v0.12 as soon as possible due to numerous security fixes. A decoder that parses untrusted input is exactly the kind of component where that matters, and it means the version your distribution packages is a question worth answering before you deploy. The repository also carries SECURITY.md, a fuzzing workflow, and a conformance workflow, which tells you the project treats malformed input as a first-class concern rather than an afterthought.
The third limitation is scope. libjxl is a codec, not an image pipeline. It does not resize, it does not manage a library, and it does not decide your storage layout. If you were hoping for a service, this is not one.
libjxl against jxl-rs, and against staying on WebP
The interesting comparison is jxl-rs, a JPEG XL implementation in Rust. The difference is not language preference, it is the role each project plays. libjxl is the reference software named in ISO/IEC 18181-4, and the conformance suite for the format is defined separately in 18181-3 against that reference. A reimplementation is judged by whether it matches the reference, so jxl-rs is answering a question libjxl does not have to answer. If your requirement is conformance testing or producing files that are definitionally correct, the reference implementation is the safer starting point. If your requirement is embedding a decoder in a Rust codebase without a C dependency, the reimplementation is the one that fits, and you accept that its correctness is defined relative to libjxl.
The other comparison people reach for is WebP. The README does not make a WebP comparison, and it should not be expected to, because the two formats were designed under different constraints. What the README does document is a capability WebP does not have: lossless recompression of existing JPEG files with reconstruction of the original JPEG on decode. If your image corpus is already JPEG, that single property can decide the choice regardless of how the two formats compare on fresh encodes.
Licence and what the PATENTS file actually says
libjxl is available under a 3-clause BSD licence, found in the LICENSE file, with an additional IP rights grant described in PATENTS. The README is unusually explicit about why that second file exists and why it names only Google: Google is the legal entity receiving Contributor License Agreements from all contributors to the JPEG XL Project, including the initial main contributors to the format, Cloudinary and Google.
For an engineer deciding whether to ship this, the practical reading is that the code licence is permissive and the patent question is handled by a separate grant rather than left silent. That is a better position than a bare BSD grant with no patent language. It is not the same as a royalty-free assurance covering every patent that might read on the format, and the BSD-3-Clause text itself says nothing about patents. If your organisation has a patent review process, PATENTS is the file to send it, and this is a question for your own counsel rather than something the README resolves.
Upgrade cost is mostly a function of how you consume the project. Following releases means tracking the CHANGELOG, and the release history shows a cadence of roughly a few months between minor versions, with patch releases for fixes. Distribution packages will lag that cadence, sometimes by a lot, which is the gap that matters if you are relying on a packaged cjxl rather than a build you control.
Editorial conclusion
Adopt libjxl if you need to write or read spec-conformant .jxl files, or if lossless JPEG recompression is the goal, because that is exactly what cjxl and djxl do by default. Do not adopt it expecting a frozen C API: the README states the library API and command line options are subject to change, so anything you link against libjxl needs to track releases. Before you commit, verify the two things the README leaves open, namely which version your distribution actually packages and whether your own build environment produces the same cjxl output as the released binaries.
Frequently asked questions
What is libjxl?
It is the reference implementation of JPEG XL, providing both an encoder and a decoder. The repository builds the cjxl and djxl command line tools, and the library itself is used by applications that support JPEG XL.
How can I open a JXL file?
Use djxl, which decodes JPEG XL files, for example by running djxl input.jxl output.png. The README also points to a list of applications that support JPEG XL, which is where to look if you want a graphical tool.
Will JXL replace JPEG?
The README does not make a prediction about format adoption, so this cannot be answered from the repository. What it does document is that cjxl can losslessly recompress existing JPEG files and djxl can reconstruct the original JPEG, which makes coexistence with JPEG part of the design rather than a replacement scenario.
What is the .JXL file format?
JPEG XL was standardized in 2022 as ISO/IEC 18181. The core codestream is specified in part 1 and the file format in part 2, with decoder conformance in part 3 and the reference software in part 4.
How does libjxl compare to jxl-rs?
libjxl is the reference software named in ISO/IEC 18181-4, so a reimplementation such as jxl-rs is measured against it rather than the other way around. Choosing between them is mostly about whether you want the reference implementation or a decoder that fits a Rust codebase without a C dependency.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/libjxl-libjxl)