`z3cli` a command line tool for working with s3 object storages

z3cli:

About

After already posting about it in some of the recent “Whats everybody working on”-threads[1][2], maybe its time for a showcase thread.

For the last few months I’ve been consistently working on z3cli, a cli tool for working with s3 storages (similar to tools like aws cli, mc, rclone). It’s kind of an (unofficial) cli frontend for the z3 Zig s3 library to which I’ve been contributing regularly too.

Just as background story: My main motivation stems from my job. I’m working for a big public institution and am responsible for administrating our object storage server systems. Somehow, I’ve been more or less unhappy with the existing s3 cli tools named above. And since I’m exploring Zig for about a year and changed to it as my main programming language at the beginning of 2026, it was just a logical decision to use it for coding an s3 tool which fits my needs better while also learning the language.

Usage and Features

Generally, z3cli should support most basic S3 features and some of the more specific. However, it is not my goal to support any operation defined by Amazons S3 AWS spec. In particular, I’m ignoring those API calls which are used almost only by AWS itself and the IAM stuff.

For now, the tool roughly supports the following operations. Every main item reflects a subcommand for z3cli:

head

  • Execute HEAD calls on buckets and objects, for the latter also on specific versions.
  • Return most helpful information for objects.

list

  • list buckets for a specific profile.
  • list objects and object versions inside a particular bucket.
  • list incomplete multipart uploads inside a particular bucket.
  • list all contents filtered by common prefix or recursive.

put

  • Upload single local files.
  • Upload content of local directories recursivley creating similar prefixes for all single objects.
  • Upload bucket policies in json formatting.
  • Upload bucket lifecycle configuration in xml formatting.

get

  • Download single objects to local file.
  • Download objects matching a specific prefix recursively into a local directory.
  • Download bucket policy in json format (printing to stdout).
  • Download bucket lifecycle configuration, formatted as plain text or json (printing to stdout).

delete

  • Delete single objects (with versioning enabled creating a delete marker).
  • Delete specific object versions.
  • Delete objects matching a named prefix recursively (or creating delete markers for them).
  • Delete all versions for objects matching a named prefix recursively (also deleting deletion markers; powerful but potentially harmful).
  • Delete incomplete multipart uploads by upload-id.
  • Delete bucket policies.
  • Delete bucket lifecycle configurations.
  • Delete buckets (if called recursively, empty the buckets first using recursive object versions deletion).

The named API calls are refined by global options (selecting profile, setting log level, forcing path-style requests, setting output formatting etc.), as well as options only valid for the selected subcommand. Thus, the general usage looks like this:

z3 [GLOBAL OPTIONS] SUBCOMAND [SUBCOMMAND OPTIONS] [POSITIONAL ARGUMENTS]

Positional arguments can either be a local path or a s3 string/URI. The latter following the spec from aws cli.

Comparison

I compared z3cli to some of the named alternative cli tools. So far, its very fast in comparison (but also lacking some of the features other tools provide). Simple benchmarks can be found here.

Conclusion

By now, I use z3cli as my daily driver for working with buckets and objects on our storage systems. Thus, I’m constantly working on and improving the tool since issues come up quickly due to the regular usage. I still use the other tools along the way to compare and test calls. But the need to use them because they provide features z3cli is not capable of yet decreases really fast over the last weeks.

In general, I’m really happy with z3cli :slightly_smiling_face:

If someone here tries it out and finds some issues, please report it in the upstream repo. There are so many S3 storage implementations out there, that more feedback is always very valuable. The same accounts for plain Zig code enhancements.

Supported Zig versions

0.16.0

AI / LLM usage disclosure

No AI/LLM’s used. Never for nothing.


  1. What’s everybody working on? (August Edition) - #24 by lukeflo ↩︎

  2. What's everybody working on? (September Edition) - #75 by lukeflo ↩︎

10 Likes

Some more helpful features added through the last two weeks:

  • Load credentials not only through config file, but also from AWS_* env vars and directly through CLI arguments.
  • Automatic content-/mime-type detection for files before uploading using zmime fork. Works with recursive uploads of dircontents too.
    • Also add CLI argument to define custom content/mime-types.
  • Show and set current BucketVersioning status.
  • And maybe most helpful: Added shell completions for almost all options and positional arguments (only zsh for now). This can be a real advantage especially for those CLI tools using multiple arguments per execution.