Lightweight, beautiful and user-friendly interactive CLI prompts library with promise-based API
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Main prompting functionality providing the core API for creating interactive CLI prompts with single or multiple questions, validation, callbacks, and dynamic question flow.
const prompts = require('prompts');
// Or for specific imports:
const { prompt, inject, override } = require('prompts');The primary function for creating interactive prompts. Accepts single question objects or arrays of questions and returns a promise with user responses.
/**
* Prompt for a series of questions
* @param questions - Single question object or Array of question objects
* @param options - Optional configuration for submit and cancel callbacks
* @returns Promise resolving to object with values from user input
*/
function prompts(
questions: Question | Question[],
options?: PromptOptions
): Promise<Answers>;
// The main export can be used directly or via the prompt property
const prompts = require('prompts');
// Both of these are equivalent:
prompts({ type: 'text', name: 'username', message: 'Username?' });
prompts.prompt({ type: 'text', name: 'username', message: 'Username?' });
interface Question {
/** Prompt type or function returning type. If falsy, question is skipped */
type: string | ((prev: any, values: Answers, prompt: Question) => string | null);
/** Property name for response object or function returning name */
name: string | ((prev: any, values: Answers, prompt: Question) => string);
/** Display message for user or function returning message */
message: string | ((prev: any, values: Answers, prompt: Question) => string);
/** Default/initial value or function returning initial value */
initial?: any | ((prev: any, values: Answers, prompt: Question) => Promise<any> | any);
/** Custom formatter for user input. Receives value and all answers */
format?: (val: any, values: Answers) => any | Promise<any>;
/** Validation function. Returns true if valid, error message string if invalid */
validate?: (val: any, values: Answers) => boolean | string | Promise<boolean | string>;
/** Render callback receiving kleur styling library. 'this' refers to current prompt */
onRender?: (kleur: any) => void;
/** State change callback receiving state object with value and aborted properties */
onState?: (state: { value: any; aborted: boolean }) => void;
/** Input stream. Defaults to process.stdin */
stdin?: NodeJS.ReadableStream;
/** Output stream. Defaults to process.stdout */
stdout?: NodeJS.WritableStream;
}
interface PromptOptions {
/** Callback invoked after each prompt submission. Return true to quit early */
onSubmit?: (prompt: Question, answer: any, answers: Answers) => boolean | Promise<boolean>;
/** Callback invoked when user cancels. Return true to continue prompting */
onCancel?: (prompt: Question, answers: Answers) => boolean | Promise<boolean>;
}
type Answers = Record<string, any>;Usage Examples:
const prompts = require('prompts');
// Single prompt
const response = await prompts({
type: 'text',
name: 'username',
message: 'What is your GitHub username?',
validate: value => value.length < 3 ? 'Username too short' : true
});
// Multiple prompts
const questions = [
{
type: 'text',
name: 'username',
message: 'What is your GitHub username?'
},
{
type: 'number',
name: 'age',
message: 'How old are you?',
validate: value => value < 18 ? 'Must be 18 or older' : true
},
{
type: 'confirm',
name: 'subscribe',
message: 'Subscribe to newsletter?',
initial: true
}
];
const response = await prompts(questions);
// { username: 'alice', age: 25, subscribe: true }Questions can have dynamic properties using functions that receive previous answers, enabling conditional prompts and dynamic question generation.
/**
* Dynamic question properties receive context about previous answers
* @param prev - Value from the immediately previous prompt
* @param values - Object containing all answers collected so far
* @param prompt - The previous prompt object
* @returns The computed value for the property
*/
type DynamicProperty<T> = (prev: any, values: Answers, prompt: Question) => T;Usage Examples:
const questions = [
{
type: 'text',
name: 'dish',
message: 'What is your favorite dish?'
},
{
type: prev => prev === 'pizza' ? 'text' : null, // Skip if not pizza
name: 'topping',
message: 'What is your favorite topping?'
},
{
type: 'confirm',
name: 'hungry',
message: (prev, values) => `Are you hungry for ${values.dish}?`
}
];
const response = await prompts(questions);Configure callbacks for handling prompt submission and cancellation events with support for early termination and error recovery.
/**
* Submit callback invoked after each prompt completion
* @param prompt - The completed prompt object
* @param answer - The user's answer to the prompt
* @param answers - All answers collected so far
* @returns Boolean indicating whether to quit early (true) or continue (false)
*/
type OnSubmitCallback = (
prompt: Question,
answer: any,
answers: Answers
) => boolean | Promise<boolean>;
/**
* Cancel callback invoked when user cancels a prompt
* @param prompt - The prompt that was canceled
* @param answers - All answers collected so far
* @returns Boolean indicating whether to continue (true) or abort (false)
*/
type OnCancelCallback = (
prompt: Question,
answers: Answers
) => boolean | Promise<boolean>;Usage Examples:
const questions = [
{ type: 'text', name: 'name', message: 'Your name?' },
{ type: 'number', name: 'age', message: 'Your age?' },
{ type: 'text', name: 'email', message: 'Your email?' }
];
const response = await prompts(questions, {
onSubmit: (prompt, answer, answers) => {
console.log(`Got ${answer} for ${prompt.name}`);
// Quit early if name is 'admin'
return answers.name === 'admin';
},
onCancel: (prompt, answers) => {
console.log('User canceled. Continuing...');
return true; // Continue prompting
}
});Input validation with custom validator functions supporting both synchronous and asynchronous validation logic.
/**
* Validation function for user input
* @param value - The user's input value
* @param values - All answers collected so far
* @returns true if valid, error message string if invalid, or Promise resolving to same
*/
type ValidateFunction = (
value: any,
values: Answers
) => boolean | string | Promise<boolean | string>;Usage Examples:
const questions = [
{
type: 'text',
name: 'email',
message: 'Enter your email:',
validate: value => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(value) || 'Please enter a valid email address';
}
},
{
type: 'number',
name: 'port',
message: 'Enter port number:',
validate: async (value) => {
if (value < 1024) return 'Port must be 1024 or higher';
if (value > 65535) return 'Port must be 65535 or lower';
// Async validation - check if port is available
const isAvailable = await checkPortAvailability(value);
return isAvailable || `Port ${value} is already in use`;
}
}
];Transform user input before storing in the response object using custom format functions.
/**
* Format function for transforming user input
* @param value - The user's raw input value
* @param values - All answers collected so far
* @returns Transformed value to store in response object
*/
type FormatFunction = (value: any, values: Answers) => any | Promise<any>;Usage Examples:
const questions = [
{
type: 'text',
name: 'name',
message: 'Enter your name:',
format: value => value.trim().toLowerCase()
},
{
type: 'number',
name: 'price',
message: 'Enter price:',
format: value => {
// Format as currency
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
}).format(value);
}
}
];Install with Tessl CLI
npx tessl i tessl/npm-prompts