Inquirer.js - Créez des CLI Node.js interactives et robustes

Léon Weiss .

27 février 2026

Commandes pour utiliser le module npm nodebook : installation, aide, et exemples d'utilisation.
Quand je construis un outil de ligne de commande en Node.js, je veux surtout éviter trois choses: des questions illisibles, une logique de saisie dispersée et une expérience qui se casse dès qu’on ajoute une branche. Inquirer.js répond précisément à ce point de friction en apportant des invites interactives prêtes à l’emploi, avec validation, sélection, mot de passe, recherche et gestion propre des réponses. Ici, je montre à quoi sert vraiment cette bibliothèque, comment l’installer sans partir sur une ancienne API, quels prompts choisir et où se trouvent ses limites.

Ce qu’il faut retenir pour une CLI Node.js interactive

  • La bibliothèque sert à créer des questionnaires de terminal clairs, guidés et validés sans écrire toute la mécanique à la main.
  • Pour un nouveau projet, je pars plutôt sur @inquirer/prompts, et sur @inquirer/core seulement si j’ai besoin d’un prompt sur mesure.
  • Les types les plus utiles sont input, confirm, select, checkbox, search, password, number et editor.
  • Le support du français existe via @inquirer/i18n, ce qui évite de bricoler les libellés à la main.
  • La contrainte principale reste l’interactivité réelle du terminal: sans TTY, le prompt ne se comporte pas correctement.

Pourquoi cette bibliothèque reste utile dans un outil CLI

Je l’utilise quand un outil doit guider l’utilisateur sans lui faire perdre de temps. Le vrai gain n’est pas décoratif; il est dans une UX plus nette et moins de logique maison à maintenir côté code. Quand je prépare un script de configuration, un assistant d’installation, un outil d’administration ou un générateur de projet, je préfère laisser la bibliothèque gérer le flux de saisie plutôt que de reconstruire tout le comportement à la main avec des événements clavier et de l’état dispersé.

Ce qui me plaît, c’est aussi la lisibilité. Une CLI mal pensée demande souvent de relire deux fois la même question, de comprendre si la réponse attendue est libre ou fermée, puis de deviner comment revenir en arrière. Avec un bon prompt, l’utilisateur comprend immédiatement ce qu’il doit faire, et le code reflète cette intention au lieu de la cacher derrière du code impératif un peu pénible à suivre.

Je réserve donc ce type d’outil aux scénarios où il faut poser plusieurs questions, valider des valeurs et enchaîner des choix. Pour une seule saisie triviale, un module plus bas niveau peut suffire. C’est justement pour ça que je regarde toujours la version du paquet et la façon de l’importer avant de brancher le moindre prompt.

Installer la bonne brique sans tomber sur l’ancienne API

Le point important aujourd’hui est d’éviter les tutoriels qui reposent encore sur l’ancienne API unique. La branche actuelle a été réécrite pour alléger le paquet et améliorer les performances; le paquet historique existe toujours pour la compatibilité, mais je ne le choisis plus pour un nouveau projet.

npm install @inquirer/prompts

import { input } from '@inquirer/prompts';

const answer = await input({ message: 'Quel est ton prénom ?' });

Si je dois construire un prompt spécifique, je passe à @inquirer/core. Si l’outil doit parler français sans bricolage localisé à la main, je regarde @inquirer/i18n, qui peut lire les variables LANGUAGE, LC_ALL, LC_MESSAGES et LANG, puis retomber sur Intl si besoin. Je peux aussi forcer un import dédié comme @inquirer/i18n/fr. Quand j’ai besoin d’aller plus loin, je garde en tête les fonctions de localisation personnalisée, mais je ne les sors que pour des CLI qui doivent durer et évoluer.

Cette distinction évite de surcharger le projet dès le départ, et elle mène naturellement au vrai sujet pratique: quel prompt choisir pour quelle interaction.

Interface en ligne de commande Node.js avec le module inquirer.js, proposant un menu interactif pour choisir une option.

Les prompts essentiels et ce que chacun résout

Je choisis les invites comme je choisirais un type de champ dans une interface web: je ne prends pas le plus riche, je prends le plus juste. Un bon prompt réduit l’effort cognitif, évite les réponses ambiguës et garde le terminal lisible, même quand le flux comporte plusieurs étapes.

Prompt Quand je l’utilise Ce que ça m’apporte
input Nom, e-mail, identifiant court, valeur simple Le plus direct, avec validation légère
confirm Décision binaire Évite les réponses ambiguës
select Une seule option dans une liste courte Lisible, rapide, sans saisie libre
checkbox Plusieurs choix possibles Pratique pour des options combinables
search Liste longue ou catalogue important Réduit le temps de navigation
password Secret, jeton, mot de passe Masque la saisie
number Port, délai, quantité, seuil Validation numérique intégrée
editor Message long, description, JSON, texte multi-ligne Confortable quand la saisie dépasse une ligne

Je réserve search aux listes qui dépassent franchement ce qu’un select peut montrer confortablement. rawlist et expand me servent plus rarement, mais ils restent utiles quand je veux des raccourcis clavier explicites ou un affichage plus compact. Le bon réflexe, c’est de faire correspondre la forme du prompt à la forme réelle de la décision.

Une fois le bon prompt choisi, le vrai travail commence: rendre le parcours fluide, réversible et simple à maintenir.

Écrire un flux de questions propre et robuste

Ce qui fait la différence entre une CLI agréable et une CLI pénible n’est pas la quantité de prompts, mais la manière de les enchaîner. Je garde les messages courts, j’ajoute des valeurs par défaut quand elles ont du sens, et je fais en sorte que chaque réponse conditionne la suivante de façon explicite.

import { input, confirm } from '@inquirer/prompts';

const sendEmail = await confirm({
  message: 'Autoriser l’envoi d’e-mails ?',
});

const email = sendEmail
  ? await input({ message: 'Adresse e-mail' })
  : null;

Je traite aussi l’arrêt du prompt comme un cas normal. Un utilisateur peut faire Ctrl+C, et le programme doit sortir proprement sans afficher une pile d’erreurs inutile. Quand j’ai une question qui ne doit pas rester ouverte indéfiniment, j’utilise un AbortSignal, par exemple avec AbortSignal.timeout(5000), pour convertir l’attente en abandon contrôlé. Quand je veux nettoyer le terminal une fois la réponse capturée, je passe clearPromptOnDone dans le contexte. Si je veux distinguer un arrêt volontaire d’un vrai incident, je capture aussi ExitPromptError explicitement.

Pour les outils destinés à des utilisateurs francophones, je trouve plus propre de laisser le paquet d’i18n suivre la langue de l’environnement plutôt que de traduire chaque message au fil de l’eau. C’est ce genre de détail qui donne une impression de produit fini, pas juste d’outil qui fonctionne.

Ces choix d’ergonomie n’ont cependant de valeur que si le terminal reste réellement interactif, ce qui nous amène aux limites concrètes de la bibliothèque.

Les limites à connaître avant de le brancher en production

Je fais attention à trois scénarios, parce que ce sont eux qui cassent le plus souvent les intégrations: les hooks Git, les scripts lancés sans terminal interactif et les environnements où l’entrée standard est redirigée. Dans ces cas-là, Inquirer n’est pas faux, il est juste hors contexte.

Situation Ce que je choisis Pourquoi
Assistant multi-étapes avec validation Inquirer Le flux reste lisible et maintenable
Une seule question simple, script ponctuel readline Moins de dépendances et assez pour une interaction très courte
Besoin d’un prompt très spécifique @inquirer/core Je fabrique mon interface sans repartir de zéro
Base de code ancienne avec beaucoup de prompts communautaires Migration progressive Je limite le risque de casse en gardant le contexte historique

Si j’utilise husky ou lint-staged, je m’assure de démarrer un TTY, souvent via /dev/tty. Si l’entrée est pipée ou si je remplace process.stdin, je pense à process.stdin.setRawMode(true), faute de quoi les flèches ou la navigation clavier peuvent se comporter bizarrement. Avec nodemon, j’ajoute souvent --no-stdin; avec le mode watch natif de Node, ça fonctionne en général sans rustine.

Autrement dit, la bibliothèque est solide, mais elle ne remplace pas les contraintes physiques du terminal. Il faut les intégrer à la conception, pas les découvrir après la mise en production.

Les règles que j’applique avant d’en faire la base d’un assistant CLI

Je garde une règle simple: si le prompt n’aide pas à réduire une décision ou à sécuriser une entrée, il prend trop de place. Pour un outil interne, je limite le nombre de questions à l’essentiel, j’ordonne les étapes du plus simple au plus engageant, et je valide au plus près de la saisie pour éviter les surprises à la fin.
  • Je préfère confirm plutôt qu’une saisie libre dès qu’il n’y a que deux issues possibles.
  • Je réserve editor aux contenus longs, parce qu’un champ multiligne ne devrait pas être simulé au forceps dans un prompt standard.
  • Je force la locale française quand le public est clairement francophone, au lieu de compter sur un environnement de test bien configuré.
  • Je teste toujours le flux dans un vrai terminal, pas seulement dans mon IDE, pour vérifier le comportement des touches, de Ctrl+C et des redirections.
  • Je garde @inquirer/core pour les cas où la bibliothèque standard ne couvre plus mon scénario, pas comme point de départ systématique.

Au fond, Inquirer vaut surtout pour une chose: transformer un échange de terminal en parcours net, court et prévisible. C’est exactement ce qui fait gagner du temps aux utilisateurs, et ce qui rend un outil CLI agréable à maintenir côté code.

Questions fréquentes

Inquirer.js simplifie la création d'interfaces de ligne de commande interactives et conviviales. Il gère les validations, les sélections et les entrées complexes, offrant une meilleure UX et réduisant le code "maison" à maintenir, surtout pour les scripts de configuration ou les assistants.
Pour un nouveau projet, installez `@inquirer/prompts` via npm. Évitez les anciens tutoriels qui utilisent l'API unique. Si vous avez besoin d'un prompt personnalisé, `@inquirer/core` est l'option. Pour le support multilingue, `@inquirer/i18n` est recommandé.
Les prompts essentiels incluent `input` (texte simple), `confirm` (oui/non), `select` (choix unique), `checkbox` (choix multiples), `search` (liste longue), `password` (saisie masquée), `number` (valeur numérique) et `editor` (texte long). Choisissez le prompt qui correspond le mieux au type de décision ou d'information attendue.
Non, Inquirer.js a des limites. Il nécessite un terminal interactif (TTY) pour fonctionner correctement. Il peut poser problème dans les hooks Git, les scripts sans terminal ou avec une entrée standard redirigée. Des solutions existent (ex: `/dev/tty` pour Husky), mais il faut en être conscient.
Gardez les messages courts, utilisez des valeurs par défaut et conditionnez les questions. Gérez l'arrêt (Ctrl+C) proprement avec `ExitPromptError` ou `AbortSignal`. Pour le multilingue, utilisez `@inquirer/i18n` pour suivre la langue de l'environnement, offrant une expérience utilisateur plus soignée.

Évaluer l'article

Moyenne: 0.0 / 5 · 0 évaluations

Tags

inquirer js inquirer.js node.js créer cli interactives node.js prompts inquirer.js bibliothèque inquirer.js
Autor Léon Weiss
Léon Weiss
Je m'appelle Léon Weiss et j'ai huit ans d'expérience dans le développement web, avec un accent particulier sur JavaScript, le backend, NoSQL et la sécurité. Mon parcours dans ce domaine a commencé par une curiosité insatiable pour la technologie et comment elle façonne notre quotidien. J'aime explorer les défis techniques et aider les lecteurs à comprendre des concepts souvent perçus comme complexes. J'écris principalement sur des sujets liés à la sécurité des applications web et à l'optimisation des bases de données NoSQL, en m'efforçant de rendre ces informations accessibles et pratiques. Je m'engage à fournir des contenus utiles, précis et à jour, en vérifiant mes sources et en comparant les informations pour offrir une perspective claire. Mon objectif est de simplifier des sujets ardus et de suivre les tendances actuelles, afin d'aider mes lecteurs à naviguer dans le paysage en constante évolution du développement web.

Commentaires (0)

Ajouter un commentaire