mrkeyoor.com_
Sun 20 Sept 04:58 UTC
npmCLI & Toolingupdated 20 Sept 2026

prompts review

prompts 2.4.2 runs interactive questions in Node terminals and resolves one answer object. Its question types cover text, hidden input, numbers, confirmation, lists, single and multiple selection, autocomplete, dates, and toggles. A question can validate or format its value, inspect prior answers, or disappear when its dynamic type returns a falsy value. override supplies named answers from flags, while inject feeds ordered values into tests. The current release dates to 2021 and fixed a regular-expression denial of service. Our browser build failed, and the package contains no TypeScript declarations.

43.9Mdownloads / wk
Verdict

prompts 2.4.2 installed in 0.4 seconds and occupied 1 MB across 3 packages in our sandbox, with 0 audit findings, but it shipped no TypeScript declarations and its latest release is from 2021. Keep it for a settled CommonJS wizard; begin new typed CLIs with @inquirer/prompts or @clack/prompts.

We installed it

Lab card: what happened when we installed promptsScreenshot of prompts documentation
Install✓ · 0.4s3 packages on disk · 1 MB
ImportESM import works · require() works · CommonJS package
Browsern/acould not be bundled for the browser (Node-only code, most likely)
Typesno TypeScript types found
Known vulns00 critical · 0 high · 0 moderate · 0 low (npm audit)

Answers from our run

Does prompts install cleanly?

Yes. In a fresh container with an empty cache, npm install prompts finished in 0.4s, leaving 3 packages and 1 MB on disk. npm audit reported no known vulnerabilities.

Can prompts run in a browser?

Not directly: esbuild could not bundle it for the browser in our run, which normally means it depends on Node built-ins. Use it on the server, or find a browser-targeted alternative.

Does prompts work with both ESM and CommonJS?

Yes. Both import 'prompts' and require('prompts') worked in Node 22 in our run. The package is published as CommonJS.

Does prompts include TypeScript types?

No type declarations were found in our install, so TypeScript users need their own declarations.

prompts or @inquirer/prompts: which should you use?

@inquirer/prompts: Use it for actively released modular prompts with current TypeScript support. prompts 2.4.2 installed in 0.4 seconds and occupied 1 MB across 3 packages in our sandbox, with 0 audit findings, but it shipped no TypeScript declarations and its latest release is from 2021.

When should you not use prompts?

The same command must work unattended in CI, cron, or piped input and has no separate flags or config path

API stability4/5The single prompts(questionOrArray, options) call, answer-object shape, dynamic question properties, onSubmit, onCancel, override, and inject have stayed unchanged for several years. Old examples still map closely to 2.4.2. That steadiness comes with a frozen package surface: there is no exports map, no bundled declaration file, and cancellation still requires callers to recognize a partial answer object.
Docs4/5The README describes every included prompt type, shared properties, dynamic questions, validation, formatting, injected testing, overrides, stream selection, and cancellation hooks with code examples. A developer can build a complete wizard from that page. It gives less direction on non-TTY execution, CommonJS-to-ESM interop, typing, state cleanup between injected tests, and throttling asynchronous autocomplete work.
Maintenance2/5npm published version 2.4.2 on October 7, 2021 as a regular-expression denial-of-service fix. GitHub showed the unarchived repository last pushed on May 14, 2025, with an open count of 150 issues and pull requests. A terminal UI can remain useful without constant releases. This gap still means new runtime problems and requested fixes should be expected to move slower than in actively shipped alternatives.
Ecosystem4/5npm counted 59,255,789 downloads between August 19 and August 25, 2026, while GitHub showed 9,310 stars. Many build tools depend on prompts, and its compact question vocabulary is widely recognizable. Our test found only 3 installed packages and working CommonJS and ESM loading, but absent first-party types and Node-only terminal behavior limit its fit in current shared or typed packages.

Discussed on

  1. hnPrompts – Lightweight, beautiful and user-friendly interactive prompts40 points
  2. hnShow HN: Prompts – Node.js lib to create interactive CLI prompts5 points

Use it if

  • A small CommonJS setup command needs standard terminal questions with little ceremony
  • A later question should be selected or skipped from an earlier answer
  • Tests need to answer a wizard deterministically through prompts.inject
  • Flags should prefill named questions through prompts.override before any terminal interaction
Skip it if

Setup reality

We installed prompts 2.4.2 in our fresh Node 22 sandbox in 0.4 seconds. It left 3 packages using 1 MB, and npm audit found 0 known vulnerabilities. The package itself is 412 KB unpacked with 2 direct dependencies, 0 peers, and an MIT license. It declares Node 6 or newer in package metadata, but the README now asks for Node 14+. No TypeScript declarations were present, so typed projects need community types or a local wrapper.

There are no credentials or config files. There must be an interactive stdin and writable terminal output. Check process.stdin.isTTY before opening a question, then use flags, environment variables, or a config file for automation. The question name becomes the response key; duplicate names overwrite values. If a dynamic type returns null, the question contributes no key. Validate the final answer object before a command performs writes, even when each visible prompt validates its own field.

prompts is CommonJS without an exports map. require() and ESM import both worked on our Node 22 box, but ESM receives CommonJS interop rather than native named exports. The esbuild browser build failed. inject uses a module-level queue and consumes values in order, so tests sharing one process can leak answers unless they set up each case carefully. override fills by question name and can bypass the interactive path; validate overridden values at the application boundary.

Cancellation stops the chain and may return a partial object. Escape, Ctrl+C, or Ctrl+D should lead to an explicit canceled state before any side effect. onCancel can return false to stop, but callers still need required-key checks. Async validation and autocomplete suggestions run during interaction. A remote suggest function can issue a request for every keystroke unless you cache, debounce, or search a local list. prompts provides the terminal controls, not a concurrency or retry policy for callbacks.

Patterns

Collect one text answer ask-text

const prompts = require('prompts');
const { project } = await prompts({
  type: 'text', name: 'project', message: 'Project name?', initial: 'my-app'
});

The question name becomes 1 response key; reusing that name later overwrites the earlier value.

Run a sequence of questions ask-chain

const answers = await prompts([
  { type: 'text', name: 'user', message: 'User?' },
  { type: 'password', name: 'token', message: 'Token?' },
  { type: 'confirm', name: 'save', message: 'Save?', initial: false }
]);

Questions run in order, and cancellation can leave a partial object with only the earlier keys.

Mark terminal cancellation stop-on-cancel

let cancelled = false;
const answers = await prompts(questions, { onCancel() { cancelled = true; return false; } });
if (cancelled) { process.exitCode = 130; return; }

onCancel stops the chain, while the explicit flag prevents partial answers from reaching side effects.

Skip a question from the prior answer skip-dependent

const questions = [
  { type: 'confirm', name: 'typescript', message: 'Use TypeScript?' },
  { type: prev => prev ? 'select' : null, name: 'mode', message: 'Mode?', choices: [{ title: 'Strict', value: 'strict' }] }
];

Returning null creates 0 key for mode, so the caller must supply its own default.

Reject invalid text in place validate-value

const question = {
  type: 'text', name: 'email', message: 'Email?',
  validate: value => /.+@.+\..+/.test(value) || 'Enter a valid email'
};

Return true to accept or a string to display a validation message beside the current prompt.

Return one stable choice value select-one

const question = {
  type: 'select', name: 'manager', message: 'Package manager?', initial: 1,
  choices: [{ title: 'npm', value: 'npm' }, { title: 'pnpm', value: 'pnpm' }]
};

initial is the zero-based choice index, so 1 selects pnpm rather than matching a value.

Return several choice values select-many

const question = {
  type: 'multiselect', name: 'features', message: 'Features?',
  choices: [{ title: 'Lint', value: 'lint', selected: true }, { title: 'Test', value: 'test' }]
};

The answer is an array, including an empty array when the user selects 0 choices.

Normalize accepted input format-answer

const question = {
  type: 'text', name: 'slug', message: 'Slug?',
  format: value => value.trim().toLowerCase().replace(/\s+/g, '-')
};

validate sees the entered value, then format controls the value stored in the answer object.

Answer prompts without a terminal inject-tests

const prompts = require('prompts');
prompts.inject(['my-app', true]);
const result = await runWizard();

inject consumes 2 queued values globally in this example, so each test must prepare its own queue.

Fill named questions from flags override-flags

prompts.override({ project: 'api', force: true });
const answers = await prompts(questions);

override bypasses interactive entry for matching names; validate the completed answer object afterward.

Refuse a noninteractive session guard-tty

if (!process.stdin.isTTY) {
  throw new Error('Interactive terminal required; pass --config instead.');
}
const answers = await prompts(questions);

This check turns an unattended wait into an immediate failure before 1 prompt opens.

Write prompts to stderr custom-streams

const answer = await prompts({
  type: 'text', name: 'value', message: 'Value?',
  stdin: process.stdin, stdout: process.stderr
});

Using stderr keeps stdout clean for machine-readable command output such as JSON.

Alternatives

PackageRegistryPick it when
@inquirer/promptsnpmUse it for actively released modular prompts with current TypeScript support
enquirernpmUse it when forms, surveys, sorting, and custom prompt subclasses matter
@clack/promptsnpmUse it for grouped CLI flows with status messages, spinners, and explicit cancellation

More cli & tooling guides

commander · chalk · typescript · esbuild · yargs · click · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.