Ten prompt packages cover the common CLI questions
The current @inquirer/prompts bundle exports 10 prompt types: input, select, checkbox, confirm, search, password, expand, editor, number, and raw list. A program imports each as an async function and receives the selected value directly. That is easier to read than hand-built readline state, especially once a menu needs arrow keys, validation, disabled choices, pagination, or a masked password. Individual packages are also available, so a small CLI does not have to treat the all-in-one bundle as its only installation choice.
Inquirer stops at interaction. It does not parse commands, define flags, or route subcommands, so it normally sits beside a CLI framework. The boundary is sensible: Inquirer owns a live prompt, while the application decides when to ask and what to do with the answer. AbortSignal support handles cancellation and timeouts. Input and output streams can be replaced, and a completed prompt can clear itself. Those controls make it usable inside more than a toy wizard, provided the caller respects terminal ownership.
Node 20.17 is the oldest current route
The root package declares Node ^20.17.0, ^22.13.0, or >=23.5.0. That excludes older supported applications even if their code only needs a basic confirm box. The repository is a Yarn 4 monorepo split across prompt, core, testing, demo, compatibility, and tooling packages. Published modules are ESM. Check the engine range and module format before upgrading a widely installed CLI, because users experience a prompt-library incompatibility as a command that fails before asking anything.
Terminal details are the sharper edge. A custom or piped stdin may require raw mode so arrow keys arrive correctly. If another node:readline interface already owns stdin, the docs tell callers to pause it, run Inquirer, and resume it afterward. Git hooks and similar scripts often start without an interactive TTY, so the README shows attaching /dev/tty. Nodemon needs --no-stdin, while Node's own watch mode works without that switch. These recipes are specific because terminal bugs are rarely obvious from application code.
What happened when we ran it
Our Yarn install at commit 6730c32 finished in 34 seconds. It pulled 495 packages and occupied 284 MB on disk for a repository containing 252 files and about 21,999 lines of source. The root package had no build script or target, so the lab skipped the build step rather than inventing one. The project is organized as workspaces, has 5 CI workflow files, and does not include a Dockerfile or a top-level directory named tests.
The test command ran for 33 seconds and exited with code 1. Vitest reported 388 passed, 22 failed, and 1 skipped out of 411 tests across 32 files. The log tail names 5 failed test files, repeated 5,000 ms timeouts, and 13 failed snapshots; packages/number/number.test.ts accounted for 8 failures. Those are the outcomes the log proves. It does not establish whether terminal behavior, container speed, snapshots, or another condition caused each failure.
The rewrite favors functions over answer sessions
The README says Inquirer was rewritten to reduce package size and improve performance, but our lab did not benchmark either claim. The modern API asks one question per imported function. Developers can build an answers object themselves or branch between calls with normal JavaScript. The legacy inquirer package remains maintained and can coexist during migration, yet the project says it is not actively developed. Hundreds of community prompts built around the older API may not have moved, so plugin inventory should be checked before a rewrite.
Version @inquirer/prompts@8.6.0, released on 2026-08-19, combines the latest individual prompts. Its notes add an initial search value and fixes for number, confirm, and editor behavior, while warning that @inquirer/core@12.0.0 changes the useState setter type. That is a real upgrade consideration for custom prompt authors. Users who only call input() or select() see a much smaller surface than teams compiling their own render functions against core hooks.
Custom prompts have a testable rendering model
@inquirer/core treats a terminal prompt as a string renderer that reruns when state changes. Its hooks cover state, keypresses, refs, effects, memoized work, prefixes, and pagination. createPrompt() wraps that renderer and resolves when the implementation calls done. Themes can control status styles, spinners, and optional Vim or Emacs keybindings. The model feels familiar to React developers without requiring JSX, and the built-in prompts double as source examples rather than opaque widgets.
Testing support is better than many terminal libraries provide. @inquirer/testing can render one prompt, synthesize typing and keypresses, inspect the screen, and await asynchronous updates. Separate Vitest and Jest entry points can drive sequential prompts in a full CLI, including an editor mock. Import order matters, and the test guide says prompts must run sequentially. Inquirer.js is therefore best when interaction quality deserves its own tests, not when a shell script merely needs one value before continuing.

