I have just started using Node.js, and I don't know how to get user input. I am looking for the JavaScript counterpart of the python function input()
or the C function gets
. Thanks.

- 3,785
- 3
- 14
- 45
-
https://nodejs.org/en/knowledge/command-line/how-to-prompt-for-command-line-input/? https://stackoverflow.com/q/51370592/3001761? – jonrsharpe Apr 23 '20 at 18:56
-
See the official docs-https://nodejs.org/en/knowledge/command-line/how-to-prompt-for-command-line-input/ – Shubham Dixit Apr 23 '20 at 19:03
7 Answers
There are 3 options you could use. I will walk you through these examples:
(Option 1) prompt-sync: In my opinion, it is the simpler one. It is a module available on npm and you can refer to the docs for more examples prompt-sync.
npm install prompt-sync
const prompt = require("prompt-sync")({ sigint: true });
const age = prompt("How old are you? ");
console.log(`You are ${age} years old.`);
(Option 2) prompt: It is another module available on npm:
npm install prompt
const prompt = require('prompt');
prompt.start();
prompt.get(['username', 'email'], function (err, result) {
if (err) { return onErr(err); }
console.log('Command-line input received:');
console.log(' Username: ' + result.username);
console.log(' Email: ' + result.email);
});
function onErr(err) {
console.log(err);
return 1;
}
(Option 3) readline: It is a built-in module in Node.js. You only need to run the code below:
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question("What is your name ? ", function(name) {
rl.question("Where do you live ? ", function(country) {
console.log(`${name}, is a citizen of ${country}`);
rl.close();
});
});
rl.on("close", function() {
console.log("\nBYE BYE !!!");
process.exit(0);
});

- 4,503
- 4
- 21
- 42

- 3,011
- 1
- 15
- 38
This can also be done natively with promises. It is also more secure then using outside world npm modules. No longer need to use callback syntax.
Updated answer from @Willian. This will work with async/await syntax and ES6/ES7.
const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
const prompt = (query) => new Promise((resolve) => rl.question(query, resolve));
// Usage inside aync function do not need closure demo only
(async() => {
try {
const name = await prompt("What's your name: ");
// Can use name for next question if needed
const lastName = await prompt(`Hello ${name}, what's your last name?: `);
// Can prompt multiple times
console.log(name, lastName);
rl.close();
} catch (e) {
console.error("Unable to prompt", e);
}
})();
// When done reading prompt, exit program
rl.on('close', () => process.exit(0));

- 4,503
- 4
- 21
- 42

- 1,059
- 10
- 17
-
2just tested: putting the rl declaration (ine 3) inside the async-function ensures, that it goes out of scopes, no need for your very last line then. – Frank N Sep 11 '22 at 19:29
-
3
-
How can I make an outer program wait until I've collected all my input? I'm trying to store it and use it, not just print it. – Mote Zart Oct 13 '22 at 18:37
-
You can use the `readline/promises` module for the async/await syntax. – Dev-Siri Feb 13 '23 at 14:20
-
Note that as of Jan 2023, the readline/promises API is considered level 1 - experimental Non-backward compatible changes or removal may occur in any future release. Use of the feature is not recommended in production environments. – KyleMit ♦ Jan 7 at – Josh Feb 17 '23 at 19:42
If you want to use ESM (import
instead of require
):
import * as readline from 'node:readline/promises'; // This uses the promise-based APIs
import { stdin as input, stdout as output } from 'node:process';
const rl = readline.createInterface({ input, output });
const answer = await rl.question('What do you think of Node.js? ');
console.log(`Thank you for your valuable feedback: ${answer}`);
rl.close();
Source: https://nodejs.org/api/readline.html#readline
Note that this is a a new feature. From the source linked above, it seems like node v17.9.1 or above is required.

- 858
- 1
- 10
- 14
-
2Note that as of Jan 2023, the [readline/promises](https://nodejs.org/api/readline.html#promises-api) API is considered [level 1 - experimental](https://nodejs.org/api/documentation.html#stability-index) *Non-backward compatible changes or removal may occur in any future release. Use of the feature is not recommended in production environments.* – KyleMit Jan 07 '23 at 19:14
The other solutions here are either async, or use the blocking prompt-sync
. I want a blocking solution, but prompt-sync
consistently corrupts my terminal.
I found a lovely answer here which offers a good solution.
Create the function:
const prompt = msg => {
fs.writeSync(1, String(msg));
let s = '', buf = Buffer.alloc(1);
while(buf[0] - 10 && buf[0] - 13)
s += buf, fs.readSync(0, buf, 0, 1, 0);
return s.slice(1);
};
Use it:
const result = prompt('Input something: ');
console.log('Your input was: ' + result);
Disclaimer: I'm cross-posting my own answer from here.
Edit: see an improved version for Linux here.

- 2,196
- 23
- 38
-
2Great solution. Yet it would be much better for users if it was hidden behind a simple Node.js built-in function named perhaps console.read(). Above bit-mangling is not simple to understand nor to remember or type right every time you or somebody needs it. As said in the discussion at https://github.com/nodejs/node/issues/28243 if there is built-in console.log(), why isn't there built-in console.read() ? – Panu Logic Nov 15 '22 at 18:33
-
1@PanuLogic I agree. The Node dev community won't budge on this, though, and I don't get why :/. `console.read()` not being implemented I can understand because it pollutes the `console` namespace, but a global `prompt()` makes sense because we already mimic browsers with things like `setTimeout()`, so why not `prompt()` as well? Or maybe in one of the Node utils built-ins if they're concerned about new globals breaking backwards compatibility – aggregate1166877 Nov 15 '22 at 22:08
-
1I get an error on the readsync. "Error: ESPIPE: invalid seek, read". I got it to work by using the openSync method to open stdin first, as suggested here: https://stackoverflow.com/a/21132342/300213 Also, pass null as the last argument to readSync. Could be a linux thing? – user4815162342 Jan 02 '23 at 20:52
-
@user4815162342 Seems like it - I tried in a GUI-less Ubuntu 18.04 VM now and got the same error, using Node 16.13 – aggregate1166877 Jan 02 '23 at 23:30
-
1@aggregate1166877 To clarify: I fixed ESPIPE by passing null as the last argument to readSync instead of 0. This gave me an ESAGAIN error, which I fixed by getting the fd to pass to readSync with this statement: `let stdin = fs.openSync("/dev/stdin","rs");`. I suspect this is something like what readline does. I will put my complete solution in a different answer. – user4815162342 Jan 04 '23 at 16:02
This also works well:
const fs = require('fs');
process.stdin.resume();
process.stdin.setEncoding('utf-8');
let inputString = '';
let currentLine = 0;
process.stdin.on('data', inputStdin => {
inputString += inputStdin;
});
process.stdin.on('end', _ => {
inputString = inputString.replace(/\s*$/, '')
.split('\n')
.map(str => str.replace(/\s*$/, ''));
main();
});
function readLine() {
return inputString[currentLine++];
}
function main() {
const ws = fs.createWriteStream(process.env.OUTPUT_PATH);
const n = parseInt(readLine(), 10); // Read and integer like this
// Read an array like this
const c = readLine().split(' ').map(cTemp => parseInt(cTemp, 10));
let result; // result of some calculation as an example
ws.write(result + "\n");
ws.end();
}
Here my process.env.OUTPUT_PATH is set, if yours is not, you can use something else.

- 197
- 1
- 7
The answer from aggregate1166877 didn't work on linux, causing ESPIPE and ESAGAIN errors without two changes.
This solution fixes those:
let stdin = fs.openSync("/dev/stdin","rs");
const read = function(message) {
fs.writeSync(process.stdout.fd, message + " ");
let s = '';
let buf = Buffer.alloc(1);
fs.readSync(stdin,buf,0,1,null);
while((buf[0] != 10) && (buf[0] != 13)) {
s += buf;
fs.readSync(stdin,buf,0,1,null);
}
return s;
}

- 2,058
- 3
- 18
- 23
It is a form of asynchronous input/output handling in Node.js. We used standard input and output streams to interact with the user or process input and output data. I have used it in hackerank question.
process.stdin.resume();
process.stdin.setEncoding("utf-8");
var stdin_input = "";
process.stdin.on("data", function (input) {
stdin_input += input; // Reading input from STDIN using `data` event.
});
//the `end `event is used to know when input reading is complete.
process.stdin.on("end", function () {
main(stdin_input); //passing a parameter in main function
});
function main(inp){
process.stdout.write(inp);
}

- 1,673
- 7
- 24
- 38