# ouch: one CLI for tar, zip, 7z and a dozen other archive formats

> ouch wraps the usual zoo of compression tools behind three subcommands, decompress, compress and list, and infers the format from the filename. It is a convenience layer for people who are tired of remembering whether it is tar xzf or unzip, not a reimplementation of the codecs.

**ouch-org/ouch** — Painless compression and decompression in the terminal

- Repository: https://github.com/ouch-org/ouch
- Website: https://crates.io/crates/ouch
- Stars: 3,774 · Forks: 155
- Language: Rust
- License: NOASSERTION
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/ouch-org-ouch

## What ouch is for, and who actually needs it

The name expands to Obvious Unified Compression Helper, and that is the whole pitch. On a Unix system, unpacking an archive means picking the right tool first: tar for tarballs, unzip for zips, a separate binary for 7z, and another one for each streaming codec. ouch replaces that decision with a single binary that has three subcommands, decompress (alias d), compress (alias c) and list (alias l or ls).

The target user is someone who works in a terminal across several archive formats in a single session, for example a build or release engineer pulling apart a vendor tarball, a zip from a colleague and a .tar.zst from a CI artifact. The README lists the intended qualities plainly: easy to use, fast, good error messages, no runtime dependencies, plus an accessibility mode, shell completions and man pages. The accessibility mode is documented on a wiki page rather than in the README, which is worth noting if screen-reader output is the reason you are evaluating it.

It is not a codec project. The Cargo.toml shows ouch depending on flate2, bzip2, zstd, lz4_flex, brotli, snap, lzma-rust2, sevenz-rust2, zip and tar. The value ouch adds is dispatch, argument handling and error reporting on top of those crates.

## How ouch decides what to do with a filename

Format selection is driven by the output filename when compressing and by the input filename when decompressing. The README gives the example `ouch compress file.txt file.txt.lz4.zst`, where the final argument is the output and its extensions decide the pipeline. Extensions chain, so .tar.gz, or the more theatrical .tar.gz.xz.zst.gz.lz4.sz shown in the README, produce nested compression applied in order.

Aliases map onto the same handlers: tgz, tbz, txz, tzst, cbt and friends all resolve to tar, while cbz and epub resolve to zip, cb7 to 7z and cbr to rar. That matters in practice because comic and ebook archives are just renamed zip or tar files, and ouch treats them that way.

When a file has no extension at all, ouch falls back to the file signature and asks the user to confirm the guess. That confirmation step is a design choice worth knowing about before you put ouch inside a non-interactive script.

Not every format behaves the same way under the hood. The support table marks zip and 7z with a footnote stating that streaming is impossible because of the formats themselves, and marks gz, sz and zst as running compression in parallel. RAR carries a third footnote: only decompression and listing are supported, because of RAR's restrictive license.

## Installing ouch and unpacking a first archive

The README points at the Repology packaging badge for the full list and then names the common routes. On Arch Linux it is `pacman -S ouch`; on macOS, `brew install ouch`; on Windows via Scoop, `scoop install ouch`. From crates.io it is `cargo install ouch`, with a note that Ubuntu users may need clang installed to build it. Debian users can install it from the pkg.haus APT archive, which the README says is built from source at release tags for stable, testing and unstable on amd64 and arm64.

A first real use is listing before extracting, which is the habit ouch is designed to make cheap:

```bash
ouch list source-code.zip --tree
```

The README shows the resulting tree, with directories and files rendered as a nested listing, and a companion flag `--show-size` that prints the uncompressed size of each entry. Neither flag requires you to extract anything to disk.

Extraction itself takes the archive as the argument, and `--dir` redirects the output:

```bash
ouch decompress summer_vacation.zip --dir pictures
```

Multiple inputs are accepted in one invocation, as in `ouch decompress a.zip b.tar.gz c.tar`. There is also a stdin path for pipelines, where the format cannot be inferred from a path and must be given explicitly:

```bash
cat a.tar.gz | ouch decompress - --format tar.gz
```

For release binaries, the README documents Sigstore signing with cosign and gives a verify-blob command against the .sigstore.json bundle, plus a reproducibility recipe that sets SOURCE_DATE_EPOCH, remaps path prefixes and builds with `cargo build --locked --release --target <triple>`.

## Where the unified interface costs you something

The support table is the honest part of the documentation, and it is where the trade-offs live. Zip and 7z cannot be streamed, so a large zip has to be handled as a whole rather than piped through. If your workflow is built around streaming multi-gigabyte archives through a pipe, ouch is the wrong layer and you want the underlying tool directly.

RAR is decompression and listing only. The README is explicit that this is a licensing constraint rather than a technical one, and it offers an escape hatch: build without the `unrar` feature to exclude non-free code. That feature flag is the thing to check if your organisation has a policy about linking non-free components, because the default build includes it.

There is a second, quieter cost. The README's benchmark section compares ouch 0.4.0 against tar 1.34, unzip 6.00 and zip 3.0, and then states that ouch focuses heavily on usage ergonomics and nice error messages, with optimization planned for the future. Read that as a disclosure: the project does not claim to win on speed. If raw throughput is the deciding factor, the benchmark file in the repository is the place to look, not the feature list.

Finally, the CLI surface is still moving. The releases listed are 0.8.1 in July 2026, 0.8.2 at the end of August and 0.8.3 in mid-September, all within a pre-1.0 series. Scripts that depend on exact flag behaviour should pin a version.

## ouch compared with tar, unzip and atool

The obvious alternative is doing nothing and keeping the standard tools. tar and unzip are preinstalled nearly everywhere, have decades of documentation, and stream by default. Their weakness is exactly what ouch targets: you have to know which one to call, and their error messages for a truncated or mislabelled archive are famously unhelpful. ouch's claim is not new capability but a single entry point with a confirmation prompt when the extension is missing and a tree view when you only want to look.

A closer comparison is atool, the long-standing Perl wrapper that also dispatches on extension across many formats. The difference in approach is the implementation language and what comes with it. ouch is a single Rust binary with no runtime dependency, so it does not need a Perl interpreter present, and its Cargo.toml pins specific Rust crates for each codec rather than shelling out to system programs. That is a real distinction on a minimal container image where neither tar's optional compression backends nor a Perl runtime may be installed.

The cost of that approach is coverage. When you shell out to system tools, you inherit whatever the system supports. When you link crates, you get what the maintainers compiled in, which is why the RAR feature flag exists and why zip and 7z lose streaming. If you need a format outside the table, ouch has nothing to offer.

## Licence, build requirements and what upgrades cost

Cargo.toml declares `license = "MIT"`, while the repository metadata carries NOASSERTION, so the crate manifest is the clearer signal of the two. The README links to a LICENSE file at the repository root, which is the file to read rather than the badge. One dependency complicates the picture: RAR support comes through the `unrar-ng` crate behind an optional `unrar` feature, and the README says you can build without it to exclude non-free code. If you redistribute ouch binaries, that is the dependency to look at. This is a description of what the project states, not legal advice.

Upgrade cost is shaped by the Rust toolchain pin. rust-toolchain.toml pins a version and rustup installs it automatically, and Cargo.toml sets `rust-version = "1.93.0"` with `edition = "2024"`. Building from source therefore requires a recent toolchain, which matters if you compile on a distribution that ships an older rustc. The README also warns that cross-compiled targets inherit the cross Docker image's toolchain, which is not pinned by digest, so those builds are bit-for-bit reproducible only against the same cross image release. If you verify release artifacts, that caveat applies to the cross-compiled ones.

For binary installs, upgrades are a package manager operation and the cost is low. For source builds, the cost is a toolchain bump whenever the pinned version moves.

## Conclusion

Adopt ouch if you move between archive formats often and want one command with readable errors and a tree listing. Do not adopt it if you need RAR compression, streaming for zip or 7z, or a stable CLI surface across minor versions. Before rolling it out, run ouch list --tree on a representative archive from your own pipeline and check the exit code your scripts will see on a corrupt file.

## FAQ

### Does ouch support compressing RAR archives?

No. The README states that because of RAR's restrictive license, only decompression and listing are supported, and that you can disable RAR support entirely by building without the unrar feature.

### How do I install ouch on macOS, Windows or Arch Linux?

The README gives brew install ouch on macOS, scoop install ouch on Windows via Scoop, and pacman -S ouch on Arch Linux. It also lists cargo install ouch from crates.io and an APT archive at pkg.haus for Debian.

### Can ouch decompress an archive that has no file extension?

Yes. The README says that when the filename has no extensions, ouch tries to infer the format from the file signature and asks the user for confirmation.

### Can ouch read an archive from standard input?

Yes, by passing - as the input path along with the format flag, since there is no path to infer the format from. The README gives the example cat a.tar.gz | ouch decompress - --format tar.gz.

### Is ouch faster than tar and unzip?

The README's benchmark section compares ouch 0.4.0 with tar 1.34, unzip 6.00 and zip 3.0, and then notes that ouch focuses heavily on usage ergonomics and nice error messages, with optimization planned for the future. It does not present speed as the primary claim.

## Sources

- [Issues](https://github.com/ouch-org/ouch/issues)
- [ouch-org/ouch on GitHub](https://github.com/ouch-org/ouch)
- [Project website](https://crates.io/crates/ouch)
- [README](https://github.com/ouch-org/ouch/blob/main/README.md)
- [Releases](https://github.com/ouch-org/ouch/releases)

---

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