Getting started with oclif by creating a todo cli app

Nguyễn Việt Hưng
The happy lone guy
Published in
8 min readJun 24, 2018
oclif logo

Brief introduction about oclif

Right at the top of the README file in oclif github repo we have a link to the official web document of oclif. According to oclif document

oclif is a framework for building CLIs in Node. It can be used like a simple flag parser but is capable of much more. It’s designed to be extensible so that you can easily add plugins such as the update warning plugin or build your own for users to install at runtime.

The oclif generator creates a CLI project in either JavaScript or TypeScript to get you started quickly. It requires very few runtime dependencies and has extremely minimal overhead.

From the description above, we can shorten it into these info:

  • Oclif is a CLI framework
  • Oclif is extensible with plugins
  • Oclif can be used either with JavaScript or TypeScript

The only question left is what’s CLI?

CLI or Command Line Interface, is a way that user interact with the program. Before the GUI or graphical user interface which includes buttons and text boxes, we use CLI which is usually represented by a black box with white texts and we type commands into it then hope that it will spit out the output that we desired. So, Oclif helps us to develop a tool that the users can interact with it using the command prompt or terminal.

Our first project with oclif!

The main purpose of this article is to introduce you to the beauty of oclif and how you can use it and make the world the better place, starting with…a simple todo app 😄.

Our todo app will include:

  • list command — Show all added todos in list
  • add command — Add new todo into the list
  • remove command — Remove a specific todo in the list
  • interact command — This is where we make some magic with inquirer

Please note: You must have NodeJS version 8+

Setup the project structure

Project structure is one of the most important things to consider before every project. Fortunately, oclif will take care all of those things with a single simple command:

The command above consists of 3 parts:

  • npx — A npm package runner. You can learn more about this here
  • oclif — The oclif package name obviously.
  • multi — This part of the command tells oclif to generate a cli tool with multiples sub commands which are just single commands. As you can guess, replacing multi with single will make oclif to generate a single command cli tool.
  • checkme — This is the name for our cli tool. I know, I’m bad at naming stuff.

Alternatively, you can install oclif as a global package so that next time you can get rid of the npx part:

npm install -g oclif

After we execute oclif, it will ask us for some information and then begins generate our folder structure.

The folder structure that oclif gives us:

I’ll be using typescript in this article, that’s why it has the tsconfig.json file in our project folder.

There are 2 folders that we care about:

  • src/ This is where our code for the cli app goes
  • test/ This is where we write tests for our code.

Hello, world!

When we first open the src/ folder, oclif gives us a hello world example for we to getting started.

When you execute this command, this is what the app spits out:

Let’s analyze hello.ts by first open up hello.ts

Hello command code

The first line of code in our Hello class is

static description = 'describe the command here'

This line used to assign a string value to a static variable called description. You may wonder why we need this variable when we don’t even use it a single time in the rest of the code? The answer is, we don’t, that description variable is for oclif to print out when it prints the help about the command

That same explanation is also applied to the example variable which is also printed at the end of the command help in the example section.

The flags variable is a bit special, not only it’s used to print out in the help of the command but also used to define flags for the command. In the picture above, I used the --help flag to print out the help, that’s what flags are and they are printed in the options section. According to this help, you can also set the --name flag which will make the command to print out:

Noice! The word world has been replaced with the name that we specified in the --name flag. Next is the static args variable which is just like what flags do but there are 2 differences between those 2:

  • You can specify flags everywhere in every order but you have to make sure that args (arguments) are in the correct order
  • When specifying flags, you must add -- prefix before each flag name then an equal sign followed by the value of that flag, whereas with args you just have to enter the value of each arg in the correct order.

For example, if you define your command like this:

$ command [city] [country]

Then here are the results if you specify the args in different ways

$ command saigon vietnam
=> in the code: args.city = saigon & args.country => vietnam
$ command vietnam saigon
=> in the code: args.city = vietnam & args.country => saigon
$ command saigon vietnam --locale=vi
=> in the code: args.city = saigon & args.country => vietnam & flags.locale = vi
$ command --locale=vi saigon vietnam
=> in the code: args.city = saigon & args.country => vietnam & flags.locale = vi

The final component in the Hello command is the run function. This run function is where it all starts, it’s like the main function in the language C.

Alright, enough with the boring code analyzing, let’s jump to the main code.

Coding the first command

You may think that we will start by copying that hello world class into another file and rename it into something else, but no! It’s the 21st century, everybody is lazy as hell, therefor Oclif provides us with a command to generate a new command file.

Same structure with the previous command only the command arg is to specify that Oclif will generate a command and the add arg is the name of the new command.

We now received a new file called add.ts in our src and test folder. Let’s say we want to define our command like this:

$ checkme add [todo]

We can clearly see that todo is an arg, not a flag so we can write code for the add command like this:

And here is how it look when you run it

To add colors to our output there's a wide range of libraries that you can use such as:

In this app, I’m going to use chalk by first installing it using:

npm install chalk

And add it to the code

Then enjoy the satisfying output

The core

From now on, you already have the ability to create a multi-command cli tool, the rest of it is on you to decide. In this app, I’ll make a core API for the cli to interact with the todos saved in a JSON file.

First I create a new file in the api/ folder in the src/ folder:

project folder structure

Here is the code for todoAPI.ts

Just plain old file operations right?

Now with this API, I can actually add a new todo into the JSON file

Not only that, but I can also list all the todos in a table using cli-table

And also remove todo from the list using its index

Wave your flag!

Oclif provides us with a wide range of types of flag such as string, boolean…However, you can also define your own type of flag using flags.build function.

To demonstrate the boolean flag which is a boolean that doesn’t take a value, I’ll improve the add function and allow users to add todos that can initially mark as done.

Which result in a small change in the todoAPI

add (todo : string, done? : boolean) {
done = done || false
const newTodo : Todo = { done, todo }
this.todos.push(newTodo)
this.saveTodos()
}

As you can see, we don’t have to specify anything to the done flag, that’s what a boolean flag does.

Step it up with inquirer.js

Inquirer.js has acquired a reputation as a wonderful helper in creating CLI, but did you know that we can also integrate it with oclif?

To combine it with inquirer.js we must first install inquirer.js and @type/inquirer (If you use typescript)

As I mentioned before, the interact command is where I’ll combine oclif with inquirer.js, but what’s exactly the interact command? Here’s the answer

Interact mode is where you can update which todo is marked as done, vice versa.

You can probably imagine the command structure in your head. This command takes no argument and flag, instead it calls the checkbox prompt of inquirer.js to display all the todo then when the user confirms the changes by pressing the enter key, it will retrieve the todos from inquirer and update them with the associated status of each checkbox.

Inquirer returns a list of checkbox names if they are checked by the user, so we just need to loop through the todos and if it’s in the returned name list then mark it as done otherwise not done.

In conclusion

Oclif is an amazing cli framework that will definitely save you a significant amount of time but still able to provide a clean, easy to use API. I hope this todo app will lay a foundation for your next amazing cli.

Now, fire up your terminal and start coding!

The full source code of this cli app can be found here:

--

--

Nguyễn Việt Hưng
The happy lone guy

A web developer who love to create everything using web technology