Menu

Node.js readline: Read User Input From the Terminal

Node.js has no prompt() function. To ask the user a question in the terminal, create a readline interface on process.stdin and call question(), or await it with readline/promises.

This page includes runnable editors. Edit, run, and see output instantly.

To read user input in Node.js, create a readline interface on process.stdin and ask with rl.question(). Node.js has no prompt(): the browser's version opens a dialog, and a terminal program has none. The modern form uses readline/promises, where await rl.question('Name? ') returns the line the user typed. Close the interface when you are done, or the program keeps waiting for more input.

question() printed its prompt, waited for one line of input, and returned it without the newline, so the program printed Next year you will be 37. For several questions, await one question() after another.

readline question() with a callback

The original API, in every Node.js version, passes the answer to a callback. Nested questions nest callbacks:

It printed the prompt, then You picked blue. The answer is a plain string, so trim it before comparing: a user who types a space after the word otherwise gets 'blue ', which is not equal to 'blue'.

Read input line by line

To process every line until the input ends, iterate the interface with for await. This is how a program reads a list typed by the user (ended with Ctrl+D) or a file piped into it with node index.js < numbers.txt. Older code does the same with events, rl.on('line', fn) for each line and rl.on('close', fn) at the end; the loop is that pair of events written top to bottom:

It printed 3 numbers, total 49, and the loop ended by itself when the input ended, so no close() is needed. Add a fourth input line, 1, and the result becomes 4 numbers, total 50.

Read all of stdin at once

For input piped from another program (cat data.txt | node index.js), reading everything in one call is simpler. File descriptor 0 is standard input. A file saved on Windows may end its lines with \r\n, so split on /\r?\n/ when the input can come from there:

It printed the three items in a column. readFileSync(0) blocks until the input is complete, which is fine for a script that reads a pipe and fine for tests, but wrong for an interactive tool, where the user would type everything before seeing any prompt.

Which one to use

All four read the same standard input. They differ in when your code gets the text: one answer at a time, one line at a time, or everything at the end.

NeedUse
Ask a few questions in orderreadline/promises with await rl.question()
Support Node.js versions before 17readline with a question() callback
Handle each line as it arrivesfor await (const line of rl)
Read a whole pipe or file from stdinfs.readFileSync(0, 'utf8')
Values known before the program startsprocess.argv instead

Common mistakes

Forgetting rl.close(). The interface keeps standard input open, so the program never exits after the last question. Close it once you have every answer.

Using the answer as a number. Like everything typed in a terminal, the answer is a string. '36' + 1 is '361'; convert with Number() first.

Piping several answers into several questions. When input comes from a pipe instead of a keyboard, readline reads all of it at once, and a line that arrives before its question() is asked is dropped. For piped input, use the for await loop or readFileSync(0).

Leaving out the output option. Without output: process.stdout, question() never prints its prompt, and the user stares at a blank terminal. The line-by-line loop does not need it, because it prints nothing.

Frequently Asked Questions

Why is prompt not defined in Node.js?

prompt() is a browser function that opens a dialog, and Node.js has no window to open it in. Use readline in Node.js, or a package such as prompts or inquirer for menus and password fields.

How do I read a password without showing it?

readline echoes every key. Packages such as prompts or @inquirer/password mask the input; doing it yourself means switching the terminal to raw mode with process.stdin.setRawMode(true) and handling each key.

Should I use readline or process.argv?

Use process.argv when the values are known before the program starts, so it can run in a script without a person present. Use readline for interactive tools that ask one question after another.

Coddy programming languages illustration

Learn to code with Coddy

Get started