# caesium-clt: a command line image compressor with lossless, lossy and resize modes

> caesium-clt is a Rust command line tool that compresses JPEG, PNG, WebP and GIF files, either losslessly through lossless optimisation or lossily at a chosen quality, and can also resize and convert them. It wraps the libcaesium engine and adds the parts a shell script wants: recursion, overwrite policies, suffixes and dry runs.

**Lymphatus/caesium-clt** — Caesium Command Line Tools - Lossy/lossless image compression tool 

- Repository: https://github.com/Lymphatus/caesium-clt
- Website: http://saerasoft.com/caesiumclt
- Stars: 575 · Forks: 47
- Language: Rust
- License: NOASSERTION
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/lymphatus-caesium-clt

## What the tool does, and which engine does the work

caesiumclt is a command line tool for image compression written in Rust, and the README presents it as covering both cases you care about: pixel-perfect lossless compression and aggressive size reduction.

The heavy lifting is delegated. The tool is built on the libcaesium engine, and the Cargo.toml pins it at 0.21.1. libcaesium is where the actual compression algorithms live, and caesium-clt is the command line surface around them, with the argument parsing, file discovery and reporting.

That division shows in the dependency list. There is clap with the derive feature for the argument parsing, indicatif with the rayon feature for the progress display, rayon itself for the parallel work, walkdir for directory traversal, infer for detecting file types, kamadak-exif for reading EXIF metadata, bytesize for human readable sizes, imagesize for reading image dimensions, colored for terminal output, and wild for glob patterns. Serde and serde_json are there for the serialisable pieces, and wild is what makes the shell style patterns in the examples work.

The package is named caesiumclt, the version is 1.5.0, the edition is 2021, and the licence in the Cargo.toml is Apache-2.0, although the repository licence is listed as something GitHub cannot classify. The author is Matteo Paonessa, the project is under the Lymphatus organisation, and the homepage is saerasoft.com/caesiumclt.

The releases are v1.5.0 on 2026-09-16, v1.4.0 on 2026-07-08 and v1.3.0 on 2026-03-31, and the last push was on 2026-10-07.

## Three compression modes, and a format table with a hole in it

The compression modes are the core decision, and there are three of them.

Quality-based lossy compression is the familiar one, where you set a number and the encoder trades fidelity for size against that target. Lossless compression preserves the image quality while reducing size, and maximum size compression targets specific file sizes, which is the mode you want when you have a hard budget rather than a quality target.

The format support table is where you should look before planning a job, because the coverage is not uniform. JPEG, PNG and WebP each support both lossy and lossless compression. GIF supports lossy only.

That gap on GIF is a real limitation, since GIF is the format you reach for when you need animation, and an animated GIF is exactly where lossy compression tends to be most visible. If your use case is animated GIFs, the lossless path is closed before you start.

Everything else is covered in both directions, and the JPEG and PNG paths are the ones with the most options, which is discussed below.

One naming detail is worth flagging. The tool is caesiumclt in package and command form, the repository is caesium-clt, and the underlying library is libcaesium, so a search for any one of them may not find the others.

## Installing it, and building it from source

Prebuilt binaries are available from the release page, and the supported platforms are Windows on x86_64, macOS on x86_64 and aarch64, and Linux on x86_64 and aarch64. So the ARM builds are covered on macOS and Linux, which is what you need for a Raspberry Pi or an Apple Silicon machine.

There are three package manager routes, one per platform's usual tool.

Cargo:

```bash
cargo install caesiumclt
```

Homebrew:

```bash
brew install caesiumclt
```

And Winget, with the SaeraSoft publisher prefix:

```bash
winget install SaeraSoft.CaesiumCLT
```

Building from source needs Rust 1.79.0 or later, and the quick start is a clone, a build and a test run:

```bash
   git clone https://github.com/Lymphatus/caesium-clt.git
   cd caesium-clt
```

```bash
   cargo build
```

```bash
   cargo build --release
```

```bash
   cargo test
```

and the tool can be run straight from the source tree with cargo run and your arguments after the double dash.

The repository has the usual supporting files: a CHANGELOG.md, a rustfmt.toml for formatting, a Cargo.lock, a docs directory with a USAGE.md for the full flag reference, and a samples directory holding test images including a JPG, a PNG, a TIF and a WebP along with level_1_0 and level_1_1 sample folders.

The continuous integration is visible in the badges at the top of the README, with separate workflows for tests, clippy and code formatting, which is the standard Rust three and means both linting and formatting are enforced on every change.

## Using it: quality, suffix, recursion and format conversion

The usage examples are the documentation that matters here, and the flag vocabulary is small enough to learn in one pass.

Lossless compression with the output directory specified is the simplest form:

```bash
# Compress a single image
$ caesiumclt --lossless -o output/ image.jpg

# Compress with metadata preservation
$ caesiumclt --lossless -e --keep-dates -o output/ image.jpg

# Compress a directory recursively
$ caesiumclt --lossless -R -o output/ Pictures

# Preserve folder structure
$ caesiumclt --lossless -RS -o output/ Pictures
```

The -R flag is recursion and -S preserves the folder structure inside the output directory. The -e flag preserves EXIF metadata and --keep-dates preserves file timestamps.

Lossy compression takes a quality number:

```bash
# Compress with quality setting
$ caesiumclt -q 80 -o output/ image.jpg

# Compress multiple images with a specific quality
$ caesiumclt -q 75 -o output/ image1.jpg image2.png image3.webp

# Compress with suffix to avoid overwriting originals
$ caesiumclt -q 85 --suffix _compressed --same-folder-as-input image.jpg
```

That last example is the pattern to keep in your head. The --suffix option adds a string to the output filename and --same-folder-as-input writes the result next to the source rather than into an output directory. Together they let you run the tool in place over your originals without overwriting them, which is what you want the first time you try it on a real photo library.

Format conversion uses --format:

```bash
# Convert images to WebP format with quality setting
$ caesiumclt -q 85 --format webp -o output/ Pictures/*.jpg

# Convert PNG to JPEG with maximum quality
$ caesiumclt -q 100 --format jpeg -o output/ image.png
```

The second example is the one to be careful with. Converting PNG to JPEG at quality 100 is not a lossless operation, whatever the quality number says, because JPEG cannot represent the alpha channel and applies lossy compression. If a PNG has transparency, that is lost.

The shell glob in the first example is expanded by your shell, not by the tool, which is why the wild dependency is there for cases where the tool itself does the matching.

## Resizing, the maximum size target, and the knobs under JPEG

Resizing has four modes, and they differ in what they hold constant.

Width and height each resize on that axis while maintaining the aspect ratio, and the long-edge and short-edge modes resize by the longest or shortest side, which the README notes is useful for a mixed set of portrait and wide photos where a fixed width would produce wildly different heights:

```bash
# Resize to specific width (maintaining aspect ratio)
$ caesiumclt --lossless --width 1920 -o output/ image.jpg

# Resize to specific height (maintaining aspect ratio)
$ caesiumclt -q 90 --height 1080 -o output/ image.jpg

$ caesiumclt -q 85 --long-edge 1500 -o output/ Pictures/*.jpg

# Resize by shortest edge
$ caesiumclt -q 85 --short-edge 800 -o output/ Pictures/*.jpg
```

The maximum size mode is the one that solves a real constraint rather than expressing a preference:

```bash
# Target a specific maximum file size (500KB)
$ caesiumclt --max-size 512000 -o output/ large-image.jpg
```

512000 bytes is 500KB, and the encoder is asked to land under it. For a CMS that rejects uploads over a limit, this is the mode that matters.

Two operational flags are worth knowing. --threads sets the worker count explicitly, and --dry-run tests the compression without writing files:

```bash
# Parallel processing with specific thread count
$ caesiumclt -q 80 --threads 4 -R -o output/ Pictures/

# Dry run to test compression without writing files
$ caesiumclt -q 80 --dry-run -o output/ Pictures/
```

The dry run is the one to reach for first on a new pipeline, since it shows what would happen without committing to the writes.

Under JPEG and PNG there are format-specific options, and the PNG one raises the optimisation level:

```bash
# PNG optimization with highest compression level
$ caesiumclt --lossless --png-opt-level 6 -o output/ image.png

# JPEG advanced options with specific chroma subsampling
$ caesiumclt -q 85 --jpeg-chroma-subsampling "4:2:0" --jpeg-baseline -o output/ image.jpg
```

Chroma subsampling is the setting that decides how JPEG handles colour detail, and 4:2:0 is the aggressive end of it, trading colour fidelity for size. The --jpeg-baseline flag produces a baseline JPEG rather than a progressive one, which matters for compatibility with older decoders and for some streaming viewers.

## Overwrite policies, and the limits of what the tool will not do

The last feature worth reading is the overwrite policy, because it decides what happens to files that already exist in the output directory.

```bash
# Never overwrite existing files
$ caesiumclt -q 85 -O never -o output/ Pictures/*.jpg

# Overwrite only if the existing file is bigger
$ caesiumclt -q 85 -O bigger -o output/ Pictures/*.jpg
```

The -O never policy refuses to touch an existing file, and -O bigger only replaces a file when the new one is smaller, which is the behaviour you want when running a compressor repeatedly over a directory, since re-running on already compressed files should not make them larger.

Those are the two policies documented. The README does not spell out what the default is when -O is not given, which is the kind of thing to determine with a dry run rather than assume.

The limits of the tool are equally clear from the feature list. It compresses, it resizes, and it converts between JPEG, PNG and WebP. It does not composite, it does not crop to arbitrary regions, and it does not produce vector output, so a workflow that needs those is looking at a different tool. GIF is the format with the reduced coverage.

The scale story is also modest. The multithreading is real, and rayon with the indicatif progress bar means a directory of thousands of images will use the machine's cores, but the parallelism is within one run over one directory. There is no recursive batch across multiple roots, and no queueing for a pipeline that stages images from several sources.

What you get is a focused, scriptable compressor with the operational options that a shell pipeline needs: an output directory, a suffix, a dry run, a thread count and two overwrite policies. The documented flag reference is in docs/USAGE.md, and the changelog at the root will tell you what changed in each version.

## Conclusion

Adopt caesium-clt when you need to shrink images from a script and want to choose between lossless optimisation and a target quality, with recursive directory handling and predictable overwrite behaviour. Do not adopt it as a general image processing suite, since resizing and format conversion are the only other operations and the format coverage is uneven, with GIF supported lossy but not lossless. Before you run it over a directory, use the dry run option first and read the overwrite policy flags, because the default behaviour on existing files is something you should confirm rather than discover after a run.

## FAQ

### What is caesium-clt and what engine does it use?

It is a command line tool for image compression written in Rust, wrapping the libcaesium engine at version 0.21.1. It handles both lossless compression and lossy compression at a chosen quality, and adds the argument parsing, directory traversal and progress reporting that a shell script needs.

### Which image formats does caesium-clt support losslessly?

JPEG, PNG and WebP support both lossy and lossless compression. GIF supports lossy only, so the lossless path is closed for animated GIFs.

### How do I install caesium-clt?

With cargo install caesiumclt, brew install caesiumclt, or winget install SaeraSoft.CaesiumCLT. Prebuilt binaries are also published on the release page for Windows x86_64, macOS x86_64 and aarch64, and Linux x86_64 and aarch64.

### How do I compress a directory of images with caesium-clt without touching my originals?

Use --suffix with a string to append to the output filename and --same-folder-as-input to write beside the source, or use the -R flag for recursion with -S to preserve the folder structure into an output directory. A --dry-run shows what would happen without writing files.

### Can caesium-clt compress an image to a specific maximum file size?

Yes, the --max-size option targets a byte limit, for example --max-size 512000 for 500KB, which is the mode to use when an upload limit rather than a quality target is your constraint.

## Sources

- [Issues](https://github.com/Lymphatus/caesium-clt/issues)
- [Lymphatus/caesium-clt on GitHub](https://github.com/Lymphatus/caesium-clt)
- [Project website](http://saerasoft.com/caesiumclt)
- [README](https://github.com/Lymphatus/caesium-clt/blob/main/README.md)
- [Releases](https://github.com/Lymphatus/caesium-clt/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/lymphatus-caesium-clt
