14 great tips to make amazing CLI applications

I discover command-line instruments an extremely solution to multiply the impression of the code they produce.

Did you write a pleasant library to wrap an API and join it to your DB mannequin? Then present a CLI software that enables anyone to question the API, work together with the DB mannequin, run the operations that you simply supplied, uncover all of the out there performance and skim the API documentation. Now you can simply write scripts that train completely different performance of your code whereas growing, create pre-commit scripts, create CICD scripts.

Listed below are a set of ideas I gathered through the years writing CLI instruments.

Use a command-line parsing framework

Whereas it’s enjoyable to parse argv by hand, I’m going straight for full-featured command-line parsing frameworks like cobra in go, clap in rust,
click in python, php-cli in PHP.

Not solely are these nicely established, they typically mean you can use subcommands, generate autocompletion script for a number of shells, deal with pretty-printing of CLI choices and hyperlink as much as configuration frameworks (see beneath).

Distribute the software as a single file with no dependencies

To make sure widespread adoption of your CLI software, it should be simply installable. Nobody needs to put in 80 node modules or god forbid, setup a python virtualenv, simply to make use of your software.

  • Golang and Rust are good languages for this, as they mean you can simply compile static binaries for a number of platforms. It’s also possible to experiment with dumping world photos in Frequent Lisp.
  • Another choice is to create a docker picture that may be run with a single docker name, though this typically makes networking and file IO extra sophisticated.
  • A compromise is to make it an simply installable package deal by your languages package deal supervisor (pip, npm, what have you ever)

Make documentation a part of the software itself

As an alternative of distributing the documentation to your software as a separate wiki, make it a part of your software. Do not spit out cryptic auto-generated argument lists, however leverage your CLI framework and TUI library to offer stunning documentation.

It must be attainable to make use of the CLI software to:

  • lookup all of the details about verbs and arguments (see the subsequent level about examples)
  • get details about the software itself and its rules of operation
  • uncover the performance supplied by the software (see the part a couple of constructing a grammar)

As complicated the git command line will be, it offers nice documentation entries for every verb.

Think about using a fairly library to render markdown straight on the command line, for instance glamour (golang) or rich (python).

Add examples to your documentation

The simplest approach to assist folks get began along with your software is to offer quite a few examples. This typically provides a extra intuitive description of arguments and the way they work together. Use it as a chance to present sure patterns and provides some background details about why a sure verb exists. Use it as a chance to additionally present complicated and superior methods of utilizing your CLI, particularly should you present filtering and templating performance (see beneath).

git, aws, kubectl all present examples that I’ve discovered extraordinarily helpful.

Make it fairly

Who would not like a fairly colourful CLI software. There are numerous terminal TUI and elegance administration libraries on the market. Do not forget to make your software appropriate to colorless terminals and IO pipes nonetheless.

imtui example

I had a good time with all of the charmbracelet libraries, like bubbletea for constructing TUIs and lipbgloss for styling. rich is an identical, superior python library.

Make it interactive

For some functions (not all), I discovered implementing an interactive model of the CLI software helpful. Usually, I’ve executed so when controlling {hardware}, the place maintaining context is essential, and far simpler in an extended operating utility.

This may be as simple as wrapping a easy stdin/stdout loop with rlwrap, all the best way to utilizing full featured TUI libraries like bubbletea (golang), textual (python) or imtui (c++.

Use asciinema to file brief tutorials

A fantastic function of command line functions is that recording a terminal session could be very light-weight, and might simply be reworked right into a gif or rendered right into a webpage.

Instruments like asciinema are nice to indicate real-life workflows.

Fastidiously craft a CLI grammar

That is what I persistently discover probably the most tough when constructing a CLI software: designing a pleasant grammar. In one of the best of worlds, verbs and subcommands are “intuitive”: if a consumer needs to do one thing, it must be simple for them to guess which command to make use of.

This implies having a set command in case you have a get command, or a correct subcommand for every useful resource that may be manipulated (for instance information, hosts, drives ).

A complicated grammar could be utilizing get --update to set a variable, or having a verb ls-files for itemizing information, and a hosts checklist subcommand and verb for itemizing hosts.

I discover that I typically must rewrite the CLI verb construction a few instances earlier than I perceive what works nicely for the issue I need to resolve. Do not attempt to get it proper the primary time, in reality avoiding being too “frameworky” or intelligent the primary time round. Liberally add the verbs and flags you discover helpful as you’re constructing out your software, after which do a second cross the place you do not thoughts restarting the verbs and flags from scratch. Chances are high that you simply construct inside helper features that may be reused.

Add structured enter and output

CLIs are usually not only for people, they’re additionally extraordinarily helpful for machines. To make it simpler to pipe and convert the information your instruments generate, take into consideration outputting structured knowledge alongside human-readable knowledge.

I’ve generic wrappers that generate:

  • tabulated, human-readable output that’s properly formatted (and coloured)
  • completely different pre-configured human readable output choices (for instance --wide, --pretty, --oneline)
  • CSV and TSV codecs for simple unix software / spreadsheet consumption
  • structured JSON output (that is often the simplest, because the objects manipulated by the CLI are sometimes serializable out of the field)
  • when relevant, dumping knowledge out as a SQLite database is extraordinarily helpful

Equally, make it simple to learn structured enter, not simply from the CLI, but additionally from information. This makes it a lot simpler to rerun comparable instructions or share massive batches of information amongst workforce members.

For good instance of those ideas, have a look at kubectl , used to managed kubernetes sources.

Add filtering and aggregation choices

Along side the earlier idea of including structured IO, think about including filtering choices. For instance, you possibly can give a consumer the choice to solely output 3 attributes as tabular knowledge, or to combination counts by a sure different attribute.

As an alternative choice to implementing your personal filtering and aggregating, which isn’t at all times simple, think about including examples the place you filter and course of knowledge by utilizing instruments like jq, yq or xsv in your CLI documentation.


Do not forget to offer copious examples (the extra helpful and relevant to the real-world, the higher). These are sometimes time-consuming to provide you with your self. Consider every helpful instance you give as a bit nugget of enjoyment when somebody will get to make use of it.

Add templating choices

If you wish to go even a step additional past structured output, think about giving the consumer the choice to offer output templates. Instruments like kubectl or aws mean you can cross your personal go-template impressed templates, making it attainable to create precisely the output wanted.

kubectl get no -o go-template='{{vary .objects}}{{if .spec.unschedulable}}{{.metadata.title}} {{.spec.externalID}}{{"n"}}{{finish}}{{finish}}'
Enter fullscreen mode

Exit fullscreen mode

I at all times discovered writing templates for CLIs fairly time-consuming, however extraordinarily helpful as soon as I figured it out. So do not skimp on examples!

Make it simple to increase your CLI

Make it simple so as to add new verbs / lengthen the CLI software. A typical sample to take action is to lookup if a binary known as yourtool-XXX exists when an unknown verb XXX is used, and cross management to that binary. That is how gh (GitHub shopper) and git function.

Even easy shell script verbs present nice extension functionality for customers. For even greater impression, present a simple wrapper framework like gh does, that enables extensions written in go to simply name the primary software itself.

Make it simple to configure your CLI

Chances are high that you’ll want to present numerous default values and configuration choices in your CLI (credentials, URL endpoints, output settings).

Make it simple to configure these by offering:

  • atmosphere variables. This has the additional advantage of creating your software simple to combine in CICD, and supply safety by avoiding itemizing credentials in your command line. It additionally permits for simple customization per listing or mission, utilizing a software like direnv.
  • configuration information. A couple of command line choice libraries present the choice to make use of a configuration file alongside the command line parser (for instance viper in golang). In any other case, nothing is less complicated to make use of a JSON, YAML, or TOML parser to learn in defaults and overrides.
  • present verbs to question and replace your config file. Loads of trendy CLI instruments present verbs to work together with their very own configuration. Good examples are git config, which offers a wealthy verb to question, take away, replace, set the git configuration. Dumping and querying the present data (alongside model, platform, loaded environments and config information) makes it simple to debug points.
  • present world and native configuration information. Moreover offering a world configuration file, enable customers to offer native configuration information. Make it simple to chain configuration information, so as to have a world config, adopted by a project-wide config (checked into git), adopted by a consumer particular override config (not checked into git).

Present autocompletion integration

Nothing is nicer for the consumer than simply urgent tab and getting a pleasant autocompletion. Shells nowadays present very nice UIs for autocompletion, and a wealthy framework to leverage these.

Moreover utilizing the builtin autocompletion technology by CLI argument parsing frameworks (see above), take into consideration offering dynamic autocompletion choices. I’ve used this up to now to dynamically question related gadgets when offering a {hardware} management software. Autocompletion would present a listing of related widgets by ID.


CLIs and TUIs are extremely efficient software for the developer. They’re often simple to jot down, extraordinarily helpful for the creator themselves as methods to train their code whereas growing, and a good way to “self-document” and lengthen the performance of the applying our library.

With a little bit of thought and styling, CLIs will be changed into recreation changers.

What about you? Do you write CLI instruments? In that case, what tips have you ever been utilizing? Are you into TUIs and interactivity?

Add a Comment

Your email address will not be published. Required fields are marked *