Getting started with oclif by creating a todo cli app

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 with 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 file in our project folder.

There are 2 folders that we care about:

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

Hello, world!

When we first open the 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 by first open up

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 . 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 variable is for oclif to print out when it prints the help about the command

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

The 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 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 flag which will make the command to print out:

Noice! The word world has been replaced with the name that we specified in the flag. Next is the 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 function. This function is where it all starts, it’s like the 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 arg is to specify that Oclif will generate a command and the arg is the name of the new command.

We now received a new file called in our and 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 file.

First I create a new file in the folder in the folder:

project folder structure

Here is the code for

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 function.

To demonstrate the boolean flag which is a boolean that doesn’t take a value, I’ll improve the 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 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 (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:

The happy lone guy

The happy lone guy blog

Nguyễn Việt Hưng

Written by

A web developer who love to create everything using web technology

The happy lone guy

The happy lone guy blog

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade