Para leer la entrada del usuario en Node.js, crea una interfaz de readline sobre process.stdin y pregunta con rl.question(). Node.js no tiene prompt(): la versión del navegador abre un diálogo, y un programa de terminal no tiene ninguno. La forma moderna usa readline/promises, donde await rl.question('Name? ') devuelve la línea que escribió el usuario. Cierra la interfaz cuando termines, o el programa se queda esperando más entrada.
question() imprimió su pregunta, esperó una línea de entrada y la devolvió sin el salto de línea, así que el programa imprimió Next year you will be 37. Para varias preguntas, espera con await un question() tras otro.
question() de readline con un callback
La API original, presente en todas las versiones de Node.js, pasa la respuesta a un callback. Las preguntas anidadas anidan callbacks:
Imprimió la pregunta y luego You picked blue. La respuesta es un string normal, así que aplícale trim antes de comparar: si el usuario escribe un espacio tras la palabra, obtiene 'blue ', que no es igual a 'blue'.
Leer la entrada línea a línea
Para procesar cada línea hasta que termine la entrada, recorre la interfaz con for await. Así es como un programa lee una lista que escribe el usuario (terminada con Ctrl+D) o un archivo que le llega por pipe con node index.js < numbers.txt. El código antiguo hace lo mismo con eventos, rl.on('line', fn) por cada línea y rl.on('close', fn) al final; el bucle es ese par de eventos escrito de arriba abajo:
Imprimió 3 numbers, total 49, y el bucle terminó solo cuando acabó la entrada, así que no hace falta close(). Añade una cuarta línea de entrada, 1, y el resultado pasa a ser 4 numbers, total 50.
Leer todo stdin de una vez
Para una entrada que llega por pipe desde otro programa (cat data.txt | node index.js), leerlo todo en una llamada es más simple. El descriptor de archivo 0 es la entrada estándar. Un archivo guardado en Windows puede terminar sus líneas con \r\n, así que separa con /\r?\n/ cuando la entrada pueda venir de ahí:
Imprimió los tres elementos en columna. readFileSync(0) bloquea hasta que la entrada está completa, lo cual está bien para un script que lee un pipe y para tests, pero no para una herramienta interactiva, donde el usuario tendría que escribirlo todo antes de ver ninguna pregunta.
Cuál usar
Las cuatro formas leen la misma entrada estándar. Se diferencian en cuándo recibe el texto tu código: una respuesta cada vez, una línea cada vez o todo al final.
| Necesitas | Usa |
|---|---|
| Hacer unas cuantas preguntas en orden | readline/promises con await rl.question() |
| Soportar versiones de Node.js anteriores a la 17 | readline con un callback en question() |
| Procesar cada línea según llega | for await (const line of rl) |
| Leer un pipe o un archivo entero desde stdin | fs.readFileSync(0, 'utf8') |
| Valores conocidos antes de que arranque el programa | process.argv en su lugar |
Errores comunes
Olvidar rl.close(). La interfaz mantiene abierta la entrada estándar, así que el programa nunca termina después de la última pregunta. Ciérrala cuando tengas todas las respuestas.
Usar la respuesta como un número. Como todo lo que se escribe en una terminal, la respuesta es un string. '36' + 1 es '361'; convierte antes con Number().
Mandar por pipe varias respuestas a varias preguntas. Cuando la entrada viene de un pipe en lugar del teclado, readline la lee toda de golpe, y una línea que llega antes de que se haga su question() se pierde. Para entrada por pipe, usa el bucle for await o readFileSync(0).
Omitir la opción output. Sin output: process.stdout, question() nunca imprime su pregunta, y el usuario se queda mirando una terminal en blanco. El bucle línea a línea no la necesita, porque no imprime nada.
Preguntas frecuentes
¿Por qué prompt no está definido en Node.js?
prompt() es una función del navegador que abre un diálogo, y Node.js no tiene ventana donde abrirlo. Usa readline en Node.js, o un paquete como prompts o inquirer para menús y campos de contraseña.
¿Cómo leo una contraseña sin mostrarla?
readline muestra cada tecla. Paquetes como prompts o @inquirer/password ocultan la entrada; hacerlo tú mismo implica poner la terminal en modo raw con process.stdin.setRawMode(true) y manejar cada tecla.
¿Uso readline o process.argv?
Usa process.argv cuando los valores se conocen antes de que arranque el programa, para que pueda ejecutarse en un script sin nadie delante. Usa readline en herramientas interactivas que hacen una pregunta tras otra.