Recently I was reviewing a sample project at work for a potential engineering candidate and was completely blown away by the prompt I was presented with from the command-line script.
I was given a list of items to pick from and was able to arrow through them (as well as use j
and k
) and it was just magnificent. It was a nice touch and I wanted to learn more about it.
After some digging, I found the package that provided all this command-line prompt goodness. The package is named inquirer
, a collection of common interactive command-line user interfaces.
The inquirer
package provides a handful of prompts out of the box and is highly configurable as well as extensible by way of a plug-in interface. It even supports promises and async/await
syntax.
š Recommended course ā¤µ
Wes Bos' Learn Node
ā About this affiliate link
Getting Started
To start adding amazing prompts to your Node.js scripts, you will need to install the inquirer
package via your package manager of choice:
# via npm $ npm install inquirer --save # via yarn $ yarn add inquirer
And within your script, be sure to require inquirer
:
const inquirer = require('inquirer');
Basic Usage
Without much configuration we can get up and running with a colorful input prompt:
const inquirer = require('inquirer'); inquirer .prompt([ { name: 'faveReptile', message: 'What is your favorite reptile?', }, ]) .then(answers => { console.info('Answer:', answers.faveReptile); });
But what if the user just hits enter? No big deal, we can add a default value for when that happens:
const inquirer = require('inquirer'); inquirer .prompt([ { name: 'faveReptile', message: 'What is your favorite reptile?', default: 'Alligators, of course!', }, ]) .then(answers => { console.info('Answer:', answers.faveReptile); });
Multiple Prompts
You may have noticed the .prompt()
method accepts an array or objects. Thatās because we can string a series of prompt questions together and all of the answers will be available by name as part of the answers
variable once all of the prompts have been resolved:
const inquirer = require('inquirer'); inquirer .prompt([ { name: 'faveReptile', message: 'What is your favorite reptile?', default: 'Alligators, of course!', }, { name: 'faveColor', message: 'What is your favorite color?', default: '#008f68', }, ]) .then(answers => { console.info('Answers:', answers); });
Different Types of Prompts
As mentioned, inquirer
does support more than just prompting a user for text input. For the sake of example, the following types will be showcased by themselves but you very well could chain them together by passing them in the same array.
List
The list
type allows you to present the user with a fixed set of options to pick from, instead of a free form input as the input
type provides:
const inquirer = require('inquirer'); inquirer .prompt([ { type: 'list', name: 'reptile', message: 'Which is better?', choices: ['alligator', 'crocodile'], }, ]) .then(answers => { console.info('Answer:', answers.reptile); });
The user can arrow up and down the list of choices as well as use j
and k
.
Raw List
Similar to list
, rawlist
displays a list of choices and allows the user to enter the index of their choice (starting at 1):
const inquirer = require('inquirer'); inquirer .prompt([ { type: 'rawlist', name: 'reptile', message: 'Which is better?', choices: ['alligator', 'crocodile'], }, ]) .then(answers => { console.info('Answer:', answers.reptile); });
Playing with this prompt type, I found it to be a bit buggy. While it does accept navigating via the arrow keys, navigating up and down between the available choices was fine, but the moment you arrowed up past the first item or arrowed down past the last option, resulted in ever increasing index values as well as NaN
showing up in the prompt.
Expandable List
The expand
type is reminiscent of some command-line applications that simply present you with a list of characters which map to functionality that can be entered. expand
prompts will initially present the user with a list of the available character values and give context to them when the key is pressed:
const inquirer = require('inquirer'); inquirer .prompt([ { type: 'expand', name: 'reptile', message: 'Which is better?', choices: [ { key: 'a', value: 'alligator', }, { key: 'c', value: 'crocodile', }, ], }, ]) .then(answers => { console.info('Answer:', answers.reptile); });
By default the H
option is included which stands for āHelpā and upon entering H
and hitting enter will switch to a list of the options, indexed by their characters that can then be entered to make a selection.
Checkbox
Thus far, weāve only talked about prompts that allow for a single selection to be made. But what if we want to allow the user to select multiple things? Thatās where the checkbox
type comes in:
const inquirer = require('inquirer'); inquirer .prompt([ { type: 'checkbox', name: 'reptiles', message: 'Which reptiles do you love?', choices: [ 'Alligators', 'Snakes', 'Turtles', 'Lizards', ], }, ]) .then(answers => { console.info('Answer:', answers.reptiles); });
Similar to the other list
types, you can use the arrow keys to navigate. To make a selection, you hit SPACE
and can also select all with a
or invert your selection with i
.
Unlike the other types weāve discussed, the answer for this prompt type will return an array instead of a string. It will always return an array, even if the user opted to not select any items.
Password
Letās say you wanted to collect some sensitive information from a user. Sure, you could simply use the input
type of prompt, but their input would be available in plain text for all to see! In those situations, use the password
prompt and the input from the user will be hidden:
const inquirer = require('inquirer'); inquirer .prompt([ { type: 'password', name: 'secret', message: 'Tell me a secret', }, ]) .then(answers => { // Logging out the secret defeats the purpose though ;) console.info('Answer:', answers.secret); });
Editor
Sometimes a command-line prompt just isnāt enough to convey a larger bit of input, like say, an essay or the contents of a log file. In those situations, the best bet is to direct the user to a full blown editor where they will have a bit more power:
const inquirer = require('inquirer'); inquirer .prompt([ { type: 'editor', name: 'story', message: 'Tell me a story, a really long one!', }, ]) .then(answers => { console.info('Answer:', answers.story); });
inquirer
will attempt to open a text editor on the userās system based on the value of the $EDITOR
and $VISUAL
environment variables. If neither are present, vim
(Linux) and notepad.exe
(Windows) will be used instead.