yesno
A lightweight Node.js library for prompting yes/no questions in CLI programs with customizable responses.
Repository Health
Technical Analysis
yesno is a small Node.js library for asking yes/no confirmation questions in command-line programs. It wraps Node’s built-in readline module in a promise-based API, prompting the user with a question and resolving to a boolean once a recognized answer is given.
By default it accepts ‘yes’/‘y’ and ‘no’/‘n’ (case-insensitive), but every part of the interaction can be customized: the accepted yes/no value sets, a default value returned on an empty response, and a custom invalid-response handler that replaces the built-in reprompt-and-retry behavior. The library has no runtime dependencies and ships its own TypeScript type definitions.
What You Get
- Promise-based
yesno({ question })API that resolves totrue/falseonce the user answers - Configurable
yesValues/noValuesarrays to accept custom responses instead of the yes/y/no/n defaults - Optional
defaultValuereturned when the user submits an empty response, with the ability to disable defaulting vianull - Override-able
invalidhandler that replaces the built-in reprompt loop with custom logic (e.g. exiting the process) - Bundled TypeScript type definitions (
yesno.d.ts) for typed usage without extra@typespackages
Common Use Cases
- Confirming a destructive CLI action (e.g. “Are you sure you want to delete/reset X?”) before proceeding
- Gating an install/setup script step behind an explicit user confirmation
- Building interactive command-line tools that need lightweight yes/no gates without a full prompt library
- Building custom confirmation flows via custom yes/no value sets (e.g. accepting domain-specific words instead of generic yes/no)
Under The Hood
Architecture
The module is a single flat file (yesno.js, ~57 lines) exporting one async function, ask, directly as module.exports. It wraps Node’s built-in readline.createInterface in a new Promise(...), taking a destructured options object (question, defaultValue, yesValues, noValues, invalid). Recognized-answer matching is done via lowercased .indexOf() checks against the yesValues/noValues arrays, falling back to a closed-over options object ({ yes: ['yes','y'], no: ['no','n'] }) when the caller doesn’t supply its own. On an unrecognized answer it invokes the invalid callback (defaulting to defaultInvalidHandler, which writes to process.stdout) and then recursively re-invokes ask() to reprompt, resolving the outer promise once a valid answer is eventually given. There is no internal state beyond the closure and no layering — the whole surface area is one function with one dependency.
Tech Stack
Plain Node.js (supports Node 8+) with zero runtime dependencies, relying only on the built-in readline module. The lone devDependency is tap (^16.3.0), invoked via tap --no-cov --no-coverage-report test/index.js. There is no build step, transpilation, or bundler — the package ships as plain CommonJS with a hand-written yesno.d.ts for TypeScript consumers. CI is a minimal GitHub Actions workflow that runs npm install then npm test on pushes to master.
Code Quality
Tests exist under test/, but they are black-box integration tests: test/index.js spawns each example script (basic.js, custom-invalid-response-handler.js, custom-response-values.js, no-default-value.js, multiple.js) as a child process with piped stdin and asserts on captured stdout, rather than unit-testing the exported ask function directly. Error handling inside the library itself is minimal: an invalid response reprompts recursively with no maximum retry count, and there is no validation of the options object’s shape. Naming is short and mostly consistent (ok, rl, yValues/nValues), though the default invalid handler still uses var/function alongside the const/arrow-function style used elsewhere. There is no linter configuration in the repository, and CI runs only npm test, no lint step.
What Makes It Unique
There is nothing novel in the technique itself — yesno is a minimal wrapper around Node’s built-in readline.question() that promisifies a single yes/no prompt with configurable accept-value lists and a pluggable invalid-response handler. Equivalent (and considerably more capable) prompting is available from libraries like inquirer, prompts, or enquirer, which support this same yes/no pattern as one of many prompt types with richer built-in features. yesno’s only distinguishing trait is its small footprint — zero dependencies, a single ~50-line file — as a narrow alternative to pulling in a full prompt toolkit for one boolean question.