Things to note when design a minimal CLI utility

"Do One Thing and Do It Well"

The UNIX philosophy is emphasized when it comes to designing CLI tools because it helps to tie together disparate tools into a unified TTY ecosystem. Each tool just "Do one thing and do it well", which makes it possible for all tools to be harmoniously connected with each other. However, I still see many old and new CLI tools that have some redundant features. These features are included with the intention of making the tool more convenient to use, but users can already achieve it by piping to existed tools relatively convenient. Redundant features in a CLI tool only make the tool more cumbersome.

Redirection

If your tool works with strings and not specifically with files, it doesn't need flags to read files like -f, --file, -i, --input... Because it's unnecessary and makes your tool a bit more complicated. You should instead allow your tool to read stdin, this syntax can be used uniformly across tools and most shells have support for redirecting data from a file into tool:

tool < input.txt
cat input.txt | tool
cat input1.txt input2.txt | tool

Similar to reading files, most shells have support for redirecting output to files:

tool > output.txt
tool >> output.txt
tool | tee output1.txt output2.txt
tool < input.txt >> output.txt

Clipboard

Your CLI tool should not have the features to get or set to the clipboard because people will use your tool in all kinds of environments, and you can't support every clipboard manager out there. But if users want your tool to interact with the clipboard, they'll be more likely to pipe it to the clipboard manager they're using:

cb | tool
tool | cb

Configuration

Don't invent a new format or new language just to config your tool:

  • If the config file only stores values, use JSON, TOML, YAML or even KDL. INI is fine, but it has some limitations and is not implement consistently. Using a common format is of course better for both developers and users. Dotfiles management tools like Home Manager can also work with these formats easier.
  • If it needs scripting, create a CLI interface so any language can call it. Or create a library / API for Lua, Python, Ruby... Don't create a dedicate programming language just to config your tool because that language will most likely limited, janky and just never be as good or as flexible as some proper languages.

Colored outputs

If your tool supports color rendering, please use 3-bit and 4-bit color as the default! I know TTY's default color isn't pleasant, but most terminal users use themes, and when they use themes they want all programs to display with the colors in the theme, not a bunch of random colors. A lot of CLI tools out there that don't follow this and choose to use Monokai, Gruvbox or their own (often really odd) colors!

Further readings

I highly recommend everyone to read Command Line Interface Guidelines, the article is not only have a guide but also gives philosophy when designing CLI.