Interactive Programs with Inquirer
Introduction
So far, we’ve written JavaScript that logs to the console or runs in the browser. But sometimes we want to build interactive command-line applications — programs where the user can choose options, enter text, or navigate menus.
The Inquirer (or @inquirer/prompts) package lets us create these interactive experiences. It’s widely used for developer tools, project generators, and demos.
Concepts
Install with:
- npm install inquirer
or
- npm install @inquirer/prompts
- Prompt the user with questions.
- Collect responses as JavaScript objects.
- Use different prompt types:
input,number,list,confirm,checkbox.
Examples
Basic Input
import { input } from '@inquirer/prompts';
// Or
// import input from '@inquirer/input';
const answer = await input({ message: 'Enter your name' });
Menu Selection
import { select } from "@inquirer/prompts";
async function showMenu() {
const choices = [
{ name: "Option 1", value: 1 },
{ name: "Option 2", value: 2 },
{ name: "Exit", value: 0 },
];
const selected = await select({
message: "Choose an option:",
choices,
});
switch (selected) {
case 1:
console.log("You chose Option 1");
break;
case 2:
console.log("You chose Option 2");
break;
case 0:
console.log("Exiting...");
break;
default:
console.log("Invalid selection");
}
}
showMenu();
Checkbox
import { checkbox, Separator } from "@inquirer/prompts";
// Or
// import checkbox, { Separator } from '@inquirer/checkbox';
const answer = await checkbox({
message: "Select a package manager",
choices: [
{ name: "npm", value: "npm" },
{ name: "yarn", value: "yarn" },
new Separator(),
{ name: "pnpm", value: "pnpm", disabled: true },
{
name: "pnpm",
value: "pnpm",
disabled: "(pnpm is not available)",
},
],
});
console.log("Answer:", answer);
Confirm
import { confirm } from '@inquirer/prompts';
// Or
// import confirm from '@inquirer/confirm';
const answer = await confirm({ message: 'Continue?' });
Search
import { search, Separator } from '@inquirer/prompts';
// Or
// import search, { Separator } from '@inquirer/search';
const answer = await search({
message: 'Select an npm package',
source: async (input, { signal }) => {
if (!input) {
return [];
}
const response = await fetch(
`https://registry.npmjs.org/-/v1/search?text=${encodeURIComponent(input)}&size=20`,
{ signal },
);
const data = await response.json();
return data.objects.map((pkg) => ({
name: pkg.package.name,
value: pkg.package.name,
description: pkg.package.description,
}));
},
});
Password
import { password } from '@inquirer/prompts';
// Or
// import password from '@inquirer/password';
const answer = await password({ message: 'Enter your name' });
Expand
import { expand } from '@inquirer/prompts';
// Or
// import expand from '@inquirer/expand';
const answer = await expand({
message: 'Conflict on file.js',
default: 'y',
choices: [
{
key: 'y',
name: 'Overwrite',
value: 'overwrite',
},
{
key: 'a',
name: 'Overwrite this one and all next',
value: 'overwrite_all',
},
{
key: 'd',
name: 'Show diff',
value: 'diff',
},
{
key: 'x',
name: 'Abort',
value: 'abort',
},
],
});
Challenges
1. Ask name/age/color
- Write a script that asks the user for their name, age, and favorite color, then prints them in a sentence.
💡 Show Answer
import { input } from "@inquirer/prompts";
const name = await input({ message: "What is your name?" });
const age = await input({ message: "What is your age?" });
const color = await input({ message: "What is your favorite color?" });
console.log(
`Your name is ${name}, you are ${age} years old, and your favorite color is ${color}.`
);
2. Menu selection
- Create a menu with options: "Say Hello", "Tell a Joke", "Exit".
- Handle each case.
💡 Show Answer
import { select } from "@inquirer/prompts";
async function showMenu() {
const choices = [
{ name: "Say Hello", value: "hello" },
{ name: "Tell a Joke", value: "joke" },
{ name: "Exit", value: "exit" },
];
const selected = await select({
message: "Choose an option:",
choices,
});
switch (selected) {
case "hello":
console.log("Hello!");
break;
case "joke":
console.log("Why did the programmer quit his job? Because he didn't get arrays.");
break;
case "exit":
console.log("Exiting...");
break;
default:
console.log("Invalid selection");
}
}
showMenu();
3. Sum three numbers
- Build a program that asks for three numbers and prints their sum.
💡 Show Answer
import { input } from "@inquirer/prompts";
async function showMenu() {
let sum = 0;
for (let i = 1; i <= 3; i++) {
const numStr = await input({
message: `Enter number ${i}:`,
});
const num = Number(numStr);
sum += num;
}
console.log(`Sum of numbers: ${sum}`);
return sum;
}
showMenu();
4. Confirm delete
- Ask the user for a yes/no confirmation before deleting something (use confirm).
💡 Show Answer
import { input, confirm } from "@inquirer/prompts";
async function showMenu() {
let sum = 0;
for (let i = 1; i <= 3; i++) {
const numStr = await input({
message: `Enter number ${i}:`,
});
const num = Number(numStr);
sum += num;
}
console.log(`Sum of numbers: ${sum}`);
const shouldDelete = await confirm({
message: "Do you want to delete the result?",
});
if (shouldDelete) {
console.log("Result deleted.");
// Add your delete logic here
} else {
console.log("Result not deleted.");
}
return sum;
}
showMenu();
5. Shopping list loop
- Create a shopping list program: ask for item names until the user types "done".
- Print the final list.
💡 Show Answer
import inquirer from "inquirer";
async function shoppingList() {
const items = [];
while (true) {
const { item } = await inquirer.prompt([
{
type: "input",
name: "item",
message:
"Enter an item for your shopping list (type 'done' to finish):",
},
]);
if (item.trim().toLowerCase() === "done") break;
items.push(item);
}
console.log("Your shopping list:");
items.forEach((item, idx) => {
console.log(`${idx + 1}. ${item}`);
});
}
shoppingList();
6. Favorite language
- Use a list prompt to ask the user which programming language they like best.
- Print a custom message for each choice.
💡 Show Answer
import inquirer from "inquirer";
async function askFavoriteLanguage() {
const { language } = await inquirer.prompt([
{
type: "list",
name: "language",
message: "Which programming language do you like best?",
choices: ["JavaScript", "Python", "Java", "C++"],
},
]);
switch (language) {
case "JavaScript":
console.log("Great choice! JavaScript is awesome for web development.");
break;
case "Python":
console.log("Python is fantastic for data science and scripting!");
break;
case "Java":
console.log("Java is powerful for enterprise applications.");
break;
case "C++":
console.log("C++ gives you control and performance!");
break;
default:
console.log("Interesting choice!");
}
}
askFavoriteLanguage();
7. Quiz game
- Build a quiz: ask three questions, keep score, and print the result at the end.
💡 Show Answer
import inquirer from "inquirer";
async function runQuiz() {
const questions = [
{
type: "list",
name: "q1",
message: "Which language runs in a browser?",
choices: ["JavaScript", "Python", "C++", "Java"],
answer: "JavaScript",
},
{
type: "list",
name: "q2",
message: "Which language is known for its indentation?",
choices: ["Java", "Python", "C++", "JavaScript"],
answer: "Python",
},
{
type: "list",
name: "q3",
message: "Which language is mainly used for Android development?",
choices: ["C++", "JavaScript", "Java", "Python"],
answer: "Java",
},
];
let score = 0;
for (const question of questions) {
const { [question.name]: userAnswer } = await inquirer.prompt([
{
type: question.type,
name: question.name,
message: question.message,
choices: question.choices,
},
]);
if (userAnswer === question.answer) {
score++;
console.log("Correct!\n");
} else {
console.log(`Wrong! The correct answer is ${question.answer}.\n`);
}
}
console.log(`Quiz finished! Your score: ${score} out of ${questions.length}`);
}
runQuiz();
8. Checkbox hobbies
- Use a checkbox prompt to let the user select multiple hobbies.
- Print them as a comma-separated string.
💡 Show Answer
import inquirer from "inquirer";
// Checkbox prompt for hobbies
const { hobbies } = await inquirer.prompt([
{
type: "checkbox",
name: "hobbies",
message: "Select your hobbies:",
choices: ["Reading", "Gaming", "Cooking", "Traveling", "Sports"],
},
]);
console.log(`Your hobbies: ${hobbies.join(", ")}`);
9. Async login
- Combine Inquirer with async functions: simulate logging into an account with a fake await login() function.
💡 Show Answer
import inquirer from "inquirer";
// Simulated async login function
async function login(username, password) {
// Simulate network delay
await new Promise((resolve) => setTimeout(resolve, 1000));
// Fake login logic
return username === "user" && password === "pass";
}
async function main() {
// Prompt for username and password
const { username, password } = await inquirer.prompt([
{ type: "input", name: "username", message: "Enter your username:" },
{ type: "password", name: "password", message: "Enter your password:" },
]);
// Simulate login
const success = await login(username, password);
if (success) {
console.log("Login successful!");
} else {
console.log("Login failed. Please try again.");
}
}
main();
10. Mini menu
- Build a mini console app with a main menu (Add, View, Exit).
- Keep the program running until the user chooses Exit.
💡 Show Answer
import inquirer from "inquirer";
const items = [];
async function mainMenu() {
while (true) {
const { action } = await inquirer.prompt([
{
type: "list",
name: "action",
message: "Main Menu:",
choices: ["Add", "View", "Exit"],
},
]);
if (action === "Add") {
const { item } = await inquirer.prompt([
{ tsype: "input", name: "item", message: "Enter item to add:" },
]);
items.push(item);
console.log(`Added: ${item}`);
} else if (action === "View") {
if (items.length === 0) {
console.log("No items to view.");
} else {
console.log("Items:");
items.forEach((item, idx) => console.log(`${idx + 1}. ${item}`));
}
} else if (action === "Exit") {
console.log("Goodbye!");
break;
}
}
}
mainMenu();