The CLI Book: Writing successful Command Line Clients with Node.js

Learn how to write successful Command Line Clients with Node.js

BUY READ

Become a successful creator

The CLI Book is your step-by-step guide to write Command Line Clients with Node.js. Learn everything what makes Command Line Clients successful and learn to compose the best Command Line Interfaces (CLI). The first part of the book explains what is needed for a successful Command Line Client, in the second part we build an application based on the learned principles. You'll get everything you need to make an impact in the areas you care about with Command Line Clients.

You'll get a DRM free PDF, EPub and Mobi and all the source code used in the book.

Happiness Guarantee

The CLI Book comes with a 100% happiness guarantee. Within 40 days of purchase you'll get a full 100% refund if you are unhappy with the book. Just send me an email and I'll refund your money 100% within 72hrs.



Preface

Command line clients are everywhere. Almost everyone, at least in tech, is using them.

There are a lot of successful command line clients out there: the Linux project has git and the Node.js project has npm. We use some of them multiple times per day. Apache CouchDB recently got nmo (speak: nemo), a tool to manage the database cluster. We can learn a lot from successful command line interfaces in order to write better command line clients.

When I started to get interested in command line clients I realised that there are a lot of discussions and informations on the web about writing APIs. The web is full of tutorials to teach you how to build APIs, especially REST-APIs, but almost nothing can be found about writing good CLIs. This book tries to explain what makes a good CLI. In the second part of the book we will build a small command line client to learn how to use Node.js to create great command line clients that people love.

The goal of the book is to show the principles to build a successful command line client. The provided code should give you a good understanding what is important to build successful command line clients and how you could implement them.

Every section has its own code examples. Before you run the code, you have to run npm install in the folder that belongs to the section.

I am very happy about feedback. Please send and feedback or corrections to theclibook@kowalski.gd. You can also contact me on twitter: @robinson_k

I hope you enjoy the book – please recommend it in case you like it.

What makes a good CLI?

In this chapter we will take a look at successful command line clients and what they are doing pretty well, which will help us to understand the problems users face using the Terminal. Understanding the problems of our users will help us to build better command line clients with Node later in the book.

Let’s take a look at how people usually use a CLI: most of the time a human sits in front of a keyboard and interacts with a terminal. We want to use simple and recognisable commands for our CLI. Sadly just easy recognisable commands don’t get us very far right now.

Maybe the problem is easier to understand if we take a look at something what I would call a bad CLI:

$ mycli -A -a 16 r foo.html
error: undefined is not a function

In my example I have to enter cryptic commands which is answered by a very cryptic error message. What does -A -a 16 and r mean? Why I am getting an error back, am I using it wrong? What does the error mean and how can I get my task done?

So what makes a good CLI? Let’s try it with the following three principles:

  • you never get stuck

  • it is simple and supports powerusers

  • you can use it for all the things!

In short: A successful CLI is successful because its users are successful and happy.

You never get stuck

Nobody likes to be in a traffic jam, stuck, just making a few meters per minute. We want to reach our target destination, that’s all we want! The same applies for our users. Both developers and users are extremely unhappy when the tools they use are standing in their way. They just want to get their task done.

So what does, „You never get stuck“ mean, exactly? It means that we should always offer our users a way to solve their task, a command should never be a dead end. Additionally the developers of the CLI should avoid every source of friction in their tool.

Let’s take a look at me, trying to use git:

$ git poll
git: 'poll' is not a git command. See 'git --help'.

Did you mean this?
  pull

In this example I entered a wrong command. git answers friendly: „Hey Robert, it looks like you entered a wrong command, but if you type in git --help, you can list all the existing commands. And hey, it just looks like you mistyped git pull, did you mean git pull?“

git offers us a way to continue our work and finish the task.

And if we take a look at npm, another successful CLI client, we’ll see the same concept:

$ npm ragrragr
Usage: npm <command>

where <command> is one of:
    access, add-user, adduser, apihelp, author, bin, bugs, c,
    cache, completion, config, ddp, dedupe, deprecate, dist-tag,
    dist-tags, docs, edit, explore, faq, find, find-dupes, get,
    help, help-search, home, i, info, init, install, issues, la,
    link, list, ll, ln, login, logout, ls, outdated, owner,
    pack, prefix, prune, publish, r, rb, rebuild, remove, repo,
    restart, rm, root, run-script, s, se, search, set, show,
    shrinkwrap, star, stars, start, stop, t, tag, test, tst, un,
    uninstall, unlink, unpublish, unstar, up, update, upgrade,
    v, verison, version, view, whoami

npm <cmd> -h     quick help on <cmd>
npm -l           display full usage info
npm faq          commonly asked questions
npm help <term>  search for help on <term>
npm help npm     involved overview

Specify configs in the ini-formatted file:
    /Users/robert/.npmrc
or on the command line via: npm <command> —key value
Config info can be viewed via: npm help config

npm@2.7.4 /Users/robert/.nvm/versions/node/v0.12.2/lib/node_modules/npm

In this example I try to put garbage into npm, so npm answers friendly: „Hey Robert, I don’t know that command, but here are all the commands that would be possible. You can use them like this and get help about them by typing in npm help <command>.“

Like git, npm immediately offers help to enable me to finish my task, even if I have no idea how to use npm at all.

Still lost?

What if I still need help? Maybe I want to get some help before I just try out commands. Turns out there is a quite reliable way to ship documentation on Unix or Linux, man-pages!

man git
Figure 1. The man-page for git pull

Man-pages are quite nice, as you don’t need the internet to open them. You can also stay in the same terminal window to read them and don’t have to switch to another window, e.g. a browser.

But some users don’t know about man-pages or they don’t like to use them. Additionally many of them will be on Windows which can’t handle man-pages natively, so git and npm offer their documentation as webpages, too:

web git
Figure 2. The documentation website of the git project

Both git and npm are making use of a trick: they write their documentation once (e.g. in Markdown or Asciidoc) and use the initital source as the base for the different formats of their docs. Later they convert them to different formats, e.g. to html.

If you take a look at the man-pages of git and npm, you will notice that their websites are basically framing the content from the man-page with a header and a sidebar.

man npm
Figure 3. The manpage for npm publish
web npm
Figure 4. The documentation website of npm

Error handling

Sometimes things go still horribly wrong… Let’s take a look at my example for a bad CLI again:

$ mycli -A -a 16 r foo.py
events.js:85
      throw er; // Unhandled 'error' event
            ^
Error: ENOENT, open 'cli.js'
    at Error (native)

In this case we are getting back a stacktrace without much context. For most people these stacktraces look quite cryptic, especially for people that don’t write Node.js on a daily basis.

And it is even worse: I really can’t tell if I just hit a bug in the command line client or if I am just using the CLI in a wrong way. Looking at that small terminal, with no idea what to do, I get extremely unhappy and so our users will get unhappy.

One thing nmo supports is „usage errors“ — here is what they look like:

$ nmo cluster dsf
ERR! Usage:

nmo cluster get [<clustername>], [<nodename>]
nmo cluster add <nodename>, <url>, <clustername>
nmo cluster join <clustername>

If a user tries to use a command in a wrong way, nmo will tell them immediately how they can use the command to get their job done. No need to open the documentation.

nmo also shows stacktraces to a user, if nmo crashes for serious reasons:

$ nmo cluster join anemone
ERR! df is not defined
ERR! ReferenceError: df is not defined
ERR!     at /Users/robert/apache/nmo/lib/cluster.js:84:5
ERR!     at cli (/Users/robert/apache/nmo/lib/cluster.js:68:27)
ERR!     at /Users/robert/apache/nmo/bin/nmo-cli.js:32:6
ERR!
ERR! nmo: 1.0.1 node: v0.12.2
ERR! please open an issue including this log on https://github.com/robertkowalski/nmo/issues

nmo adds the current nmo and node version to the stacktrace, like npm does. We also ask the user to copy the stacktrace and to open an issue containing the stacktrace.

The reports make it easy for the team to identify the bug, solve it, and release a new version of nmo by seeing the stacktrace.

And again the user is not stuck. The user gets help to solve their task, in the worst case we help them in our issue tracker.

Hi! Sorry to interrupt you!

I'm Robert Kowalski, the Author of the book.

It seems you like the book, if you have read that far!

I would like to ask you to buy the ebook version of the book. It is a nice package containing a DRM free PDF, EPub and Mobi version of the book. You can read it on your Kindle, iPad. It also works on your Mac and PC. The package also contains all the source code used in the book. Thank you!
BUY TABLE OF CONTENTS

Table of Contents

Preface

What makes a good CLI?

    You never get stuck
    • Still lost?
    • Error handling
  • It supports powerusers
    • Shortcuts
    • Scripting
    • exit codes
    • JSON output
    • The API in the Command Line Client
    • Configuration
  • You can use it for all the things!

Writing a database administration tool with Node.js

  • Why use Node.js?
  • Setup
  • Using the PouchDB database server
  • Troubleshooting

A simple status check

  • Getting started from scratch
  • The internals of the command
  • The CLI part
  • Booting the tool
  • Error handling
  • JSON support and Shorthands
  • Documentation
  • More Help
  • Configuration
  • Our first release & release tips

Migration of large amounts of data using Streams

  • The first stream
  • The Transform and Writeable stream
  • The streaming import command

Tips & Tricks

  • Testing
  • Semantic Versioning with SemVer
  • Greenkeeper


About the Author

Hi! I am Robert Kowalski, a Software Engineer specialised on Open Source Software. I am a Node.js Core Committer and I worked on the npm client for several years, where I found my love for great Command Line Interfaces. I enjoy writing and lecturing about Node.js and Command Line Clients to inspire others and to share my knowledge.


Github | Twitter

Questions?

Do you have questions about the book? I am happy to answer them! Just write me an email!

Jump to the packages