inquirer.js – Interactive command line user interface

1. What is inquirer.js

1. inquirer.js is an open source interactive command line user interface (CLI) library that allows you to easily interact with users, obtain user input and process it accordingly. Its main function is to provide a series of commonly used command line interactive interface components, such as input, confirm, list, checkbox, etc.

2. inquirer.js is a Node.js module, so it can be easily integrated with Node.js applications. Using inquirer.js, you can create sophisticated interactive command line user interfaces, making your command line applications easier to use and more user-friendly.

3. inquirer.js can also create custom functions by adopting appropriate extensibility interfaces. These custom functions can be used as plug-ins of inquirer.js.

2. How to use inquirer.js

When using inquirer.js, you need to install it in your project first, as follows:

npm install inquirer

In a Node.js application, you can use the following code example to create a simple command line prompt:

//Introduce inquirer.js
const inquirer = require('inquirer');

// Get the name from the user
inquirer.prompt([
  {
    type: 'input',
    name: 'name',
    message: 'Please enter your name:'
  }
]).then(answers => {
  console.log(`Hello, ${answers.name}!`);
});

After running the above code, it will prompt you for your name and print a “Hello, your name!” message on the console.

Please note here that Inquirer v9 and higher are native esm modules, which means you can no longer use commonjs syntax require. If you still use require, you need a lower version of Inquirer.js
npm install –save inquirer@^8.0.0

How to introduce a new version:

import inquirer from 'inquirer';

inquirer
  .prompt([
    /* Pass your questions in here */
  ])
  .then((answers) => {
    // Use user feedback for... whatever!!
  })
  .catch((error) => {
    if (error.isTtyError) {
      // Prompt couldn't be rendered in the current environment
    } else {
      // Something else went wrong
    }
  });

If used directly, an error will be reported.

Error: Loading ES module, setting “type”: “module” in packahejson or using .mjs file
In fact, the solution has been written in the error reminder, which is to add “type”: “module” to package.json.

3. Usage scenarios of inquirer.js

inquirer.js is well suited for user input scenarios when developing command line tools. Using inquirer.js, you can easily interact with end users, making your command line tools more user-friendly. The following are common usage scenarios of inquirer.js:

1. Configuration option interaction
Using inquirer.js, you can configure options interactively, allowing users to easily set or change options for your command line tool.

inquirer.prompt([
  {
    type: 'input',
    name: 'username',
    message: 'Please enter your username:',
  },
  {
    type: 'password',
    message: 'Please enter your password:',
    name: 'password',
  },
  {
    type: 'list',
    message: 'Please select your language:',
    name: 'language',
    choices: ['Chinese', 'English']
  },
]).then(answers => {
  console.log('Your username is:', answers.username);
  console.log('Your password is:', answers.password);
  console.log('The language you selected is:', answers.language);
});

2. Multiple choice interaction
Using inquirer.js, you can easily create multiple choice interactions that let users choose from a predefined set of options.

inquirer.prompt([
  {
    type: 'list',
    message: 'Please select the application you want to install?',
    name: 'app',
    choices: [
      {
        name: 'Google Chrome',
        value: 'chrome'
      },
      {
        name: 'Visual Studio Code',
        value: 'vscode'
      },
      {
        name: 'Adobe Photoshop',
        value: 'photoshop'
      }
    ],
  },
  {
    type: 'confirm',
    message: 'Are you sure you want to install it? ',
    name: 'confirm',
  },
]).then(answers => {
  if (answers.confirm) {
    console.log(`The application you selected is: ${answers.app}`);
  } else {
    console.log('Installation canceled!');
  }
});

3. Command line interaction
Using inquirer.js, you can create an interactive command line interface that allows users to interact with your application in a manner similar to running commands.

inquirer.prompt([
  {
    type: 'command',
    message: 'Please enter the command to be executed: ',
    name: 'command',
  },
]).then(answers => {
  console.log(`Execute command: ${answers.command}`);
});

4. Components of inquirer.js

inquirer.js provides a variety of interactive command line interface components, including:

1. input
Answer the string entered by the user.

inquirer.prompt([
  {
    type: 'input',
    name: 'name',
    message: 'Please enter your name:'
  }
]).then(answers => {
  console.log(`Hello, ${answers.name}!`);
});

2. confirm
A simple yes/no interaction that returns a Boolean value.

inquirer.prompt([
  {
    type: 'confirm',
    name: 'truth',
    message: 'Is the universe really infinite? ',
  }
]).then(answers => {
  if (answers.truth) {
    console.log('Correct!');
  } else {
    console.log('Error!');
  }
});

3. list
Select an item from a list.

inquirer.prompt([
  {
    type: 'list',
    name: 'color',
    message: 'Choose a color:',
    choices: ['red', 'green', 'blue'],
  }
]).then(answers => {
  console.log(`The color you selected is: ${answers.color}`);
});

4. rawlist
Similar to list, but independent of user selection.

inquirer.prompt([
  {
    type: 'rawlist',
    name: 'pet',
    message: 'What is your favorite pet? ',
    choices: ['dog', 'cat', 'rabbit'],
  }
]).then(answers => {
  console.log(`Your favorite pet is: ${answers.pet}`);
});

5. checkbox
Select multiple options from a checkbox list.

inquirer.prompt([
  {
    type: 'checkbox',
    name: 'fruits',
    message: 'Choose your favorite fruit:',
    choices: [
      {name: 'apple', value: 'apple'},
      {name: 'banana', value: 'banana'},
      {name: 'strawberry', value: 'strawberry'},
      {name: 'peach', value: 'peach'},
    ],
  }
]).then(answers => {
  console.log(`The fruit you selected is: ${answers.fruits}`);
});

6. password
Password input

inquirer.prompt([
  {
    type: 'password',
    name: 'password',
    message: 'Please enter your password:',
  }
]).then(answers => {
  console.log(`Your password is: ${answers.password}`);
});

5. Custom components of inquirer.js

In addition to providing a variety of components, inquirer.js also supports custom components. Here’s an example of a custom component that returns user input in the order it was entered:

//Custom component
inquirer.registerPrompt('order', function (questions, callback) {
  const answers = {};

  function questionLoop() {
    if (questions.length === 0) {
      callback(answers);
      return;
    }

    const currentQuestion = questions.shift();
    const {
      message,
      name
    } = currentQuestion;

    inquirer.prompt({
      type: 'input',
      message,
      name,
    }).then(answer => {
      answers[name] = answer;
      questionLoop();
    });
  }

  questionLoop();
});

// Use custom components
inquirer.prompt([
  {
    type: 'order',
    name: 'order',
    message: 'Please enter the order:',
    questions: [
      {
        message: 'First:',
        name: 'first',
      },
      {
        message: 'Second:',
        name: 'second',
      },
      {
        message: 'Third:',
        name: 'third',
      },
    ]
  }
]).then(answers => {
  console.log('The order you entered is:', answers.order);
});

6. Plug-in of inquirer.js

inquirer.js not only supports custom components, but also uses plugins corresponding to the extensibility interface to provide more functionality. Here is an example of the inquirer.js plugin that provides a way to list files and folders.

const inquirer = require('inquirer');
const fs = require('fs');

//Plugin object
const fileTree = {
  type: 'file-tree',
  async run(paths) {
    const questions = {
      type: 'list',
      name: 'path',
      message: 'Please select the path you want to access',
      choices: paths,
    };
    const {
      path
    } = await inquirer.prompt(questions);

    const stats = fs.statSync(path);
    if (stats.isDirectory()) {
      const files = fs.readdirSync(path).map(file => {
        const subPath = `${path}/${file}`;
        const stats = fs.statSync(subPath);
        return {
          name: file,
          value: stats.isDirectory() ? fileTree.run([subPath]) : subPath
        };
      });

      return inquirer.prompt({
        type: 'list',
        message: 'Please select the file or directory you want to access:',
        name: 'path', choices: files
      });
    }

    return {
      path
    };
  }
};

//Register plugin
inquirer.registerPrompt('file-tree', fileTree);

// use plugin
inquirer.prompt({
  type: 'file-tree',
  name: 'path',
  message: 'Please select the file or directory you want to access:',
  default: '.',
  run() {
    const paths = fs.readdirSync('.');
    return paths.map(path => {
      const stats = fs.statSync(path);
      return {
        name: path,
        value: stats.isDirectory() ? fileTree.run([path]) : path
      };
    });
  }
}).then(answers => {
  console.log('The selected path is:', answers.path);
});

7. Events of inquirer.js

inquirer.js provides multiple events for monitoring different operations, such as start, completion, cancellation, etc. Below is an example of an event to exit the application after confirming the cancellation ask.

const inquirer = require('inquirer');

inquirer.prompt([
  {
    type: 'confirm',
    name: 'confirmExit',
    message: 'Are you sure you want to exit? ',
  },
]).then(answers => {
  if (answers.confirmExit) {
    process.exit(0)
  }
});

//Listen to the cancellation event
inquirer.on('cancel', () => {
  console.log('You have canceled the operation!');
  process.exit(0)
});

8. Summary

In this article, we take a closer look at inquirer.js, a powerful interactive command line user interface library. We explained the features, usage scenarios, components and plug-ins of inquirer.js. Through this article, you can learn how to use inquirer.js to create repetitive CLI tools or other interactive command line interfaces and make them more user-friendly and easy to use. I hope this article can help you have a deeper understanding of inquirer.js and quickly master how to use it.