How to Easily Create CLIs Using OCLIF (and How We Did It for the Adobe I/O CLI)

Shazron Abdullah
May 23, 2019 · 5 min read

Terminals and command-line apps are hot, hot, hot right now. Microsoft just released their new Terminal, and it’s even open-sourced. If this makes you want to create your own CLI (Command Line Interface) app, we’re here to help. For simple CLIs, you can use something like TJ Holowaychuk’s (of express.js fame) commander; in fact, that’s what we started out with when we were first constructing the Adobe I/O CLI.

We needed a fully extensible CLI in the form of plugins, though, so we started work on a whole plugin system (which was not available in commander). That led to us to the solution below. Follow along to see how we created our own CLI app using OCLIF.

Meet OCLIF (Open CLI Framework)

OCLIF (Open CLI Framework) was released in March of 2018, and that’s when we came to an inflection point. Do we continue with all the work we had been doing with commander, or should we adopt OCLIF with its plugin system (and other advantages)?

Even though it meant that we would have to abandon most of our work, it was a no-brainer for our team. Our extensive experience in contributing to open source (with Adobe PhoneGap, Apache Cordova, and Apache OpenWhisk) made the decision easier: adopt OCLIF. NIH (Not Invented Here) syndrome was never in our blood.

Fun fact: Heroku was once our neighbor in San Francisco, just across the street from Adobe on Townsend Street.

OCLIF is open-sourced, MIT-licensed, and was written by Heroku. OCLIF is a CLI framework based on node.js (TypeScript or JavaScript), with a fully extensible plugin system and automatic documentation generation. It favors convention over configuration, and is very easy to develop for. Here’s everything you need to know about its implementation:

OCLIF plugins

Some of the plugins available from OCLIF include:

  1. @oclif/plugin-not-found — Display a friendly “did you mean” message if a command is not found.

OCLIF user interface components

A CLI also has other requirements, like UI functionality to better format the output or better notify the user. These node modules below work well with OCLIF:

  1. cli-ux
  • tree — formats data in a tree

2. node-notifier for cross-platform OS notifications

3. listr for complex workflows like checklists

Convention over configuration

What does ‘convention over configuration’ mean with regards to OCLIF? Here is an example folder structure for a command called “giphy,” with its sub-commands. Note that to create the command, all you need is a folder with the same name, and the sub-commands as ‘.js’ JavaScript modules inside the folder.


  • $ my-cli giphy:random

What’s with the colon (:) used to separate the command from the sub-commands?

OCLIF’s philosophy is that​ colons help the user know which arguments are the command and which are arguments to that command. However, it is ​harder to get adoption from hardened CLI users that are used to space-separated commands and sub-commands.

However, we solved it in aio-cli with our custom changes to support both space-separated and colon-separated commands.

An example command

const { Command, flags } = require(‘@oclif/command’)

class RandomCommand extends Command {
async run () {
const { flags, args } = this.parse(RandomCommand)
this.log(`args: ${JSON.stringify(args)}`)
this.log(`flags: ${JSON.stringify(flags)}`)
// TODO: call the Giphy API and get the first random gif

RandomCommand.description = ‘Grabs a random gif from giphy’

RandomCommand.args = [
name: ‘tag’,
description: ‘filters results by the specified tag’,
required: false

RandomCommand.flags = {
rating: flags.string({
char: ‘r’,
description: ‘filters results by specified rating’,
default: ‘g’,
options: [ ‘y’, ‘g’, ‘pg’, ‘pg-13’, ‘r’ ]

module.exports = RandomCommand

You can play with this example command at:


So how do you distribute your app once you’ve finished it? Do users need to install node.js beforehand on their machines? No, you will have the option to create operating system-specific binaries or containers for your CLI app:

  1. npm registry

The Adobe I/O CLI

The Adobe I/O CLI currently has four plugins:

  1. @adobe/aio-cli-plugin-config

The adobe/aio-cli-plugin-console plugin helps list and select Adobe I/O Runtime integrations.

The aio-cli-plugin-runtime plugin is a direct replacement for the ‘wsk’ and ‘wskdeploy’ CLI for Apache OpenWhisk. You can use this with Adobe I/O Runtime as well.

To install the CLI, run:

  • npm install -g @adobe/aio-cli

After the CLI is installed, to install the runtime plugin, run:

  • aio plugins:install @adobe/aio-cli-plugin-runtime

To see how to use the commands, run:

  • aio — help

More resources for you

I hope this shows you how easy it is to create your own extensible CLI, or how to create plugins for any existing OCLIF cli. Please see the links below, they provide everything you need to get started.


Follow the Adobe Tech Blog for more developer stories and resources, and check out Adobe Developers on Twitter for the latest news and developer products.

Adobe Tech Blog

News, updates, and thoughts related to Adobe, developers, and technology.

Shazron Abdullah

Written by

Base class: human. Day job: Adobe I/O. Night job: Incredible Coding Man. Now based in Singapore, previously San Francisco Bay Area, and Vancouver, BC.

Adobe Tech Blog

News, updates, and thoughts related to Adobe, developers, and technology.

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