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.
-
nodejs.org/en/knowledge/command-line/…? stackoverflow.com/q/51370592/3001761?jonrsharpe– jonrsharpe2020-04-23 18:56:51 +00:00Commented Apr 23, 2020 at 18:56
-
See the official docs-nodejs.org/en/knowledge/command-line/…Shubham Dixit– Shubham Dixit2020-04-23 19:03:04 +00:00Commented Apr 23, 2020 at 19:03
-
UPDATE: Official Docs Page has been moved to: nodejs.org/en/learn/command-line/…m-naeem66622– m-naeem666222024-03-05 08:24:11 +00:00Commented Mar 5, 2024 at 8:24
-
nodejs.org/en/learn/command-line/…Fattie– Fattie2025-07-01 13:15:35 +00:00Commented Jul 1 at 13:15
9 Answers
There are 4 options you could use. I will walk you through these examples:
(Option 1) readline (async/await):
In my opinion, it is the best option as we can get the user input asynchronously using async/await in Node.js. You need to wrap the rl.question method in a promise to make it work with async/await..
const readline = require('readline');
// Create an interface for input and output
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const askQuestion = (question) => {
return new Promise((resolve) => {
rl.question(question, (answer) => {
resolve(answer);
});
});
};
// Main async function
const main = async () => {
// Get user input using await
const name = await askQuestion('What is your name? ');
// Print the result
console.log(`Hello, ${name}!`);
// Close the readline interface
rl.close();
};
// Call the main async function
main();
(Option 2) prompt-sync: 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 3) 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 4) readline (callbacks): Another example with readline but using callbacks:
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);
});
Comments
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));
6 Comments
readline/promises module for the async/await syntax.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.
1 Comment
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.
Edit: see an improved version for Linux here.
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.
6 Comments
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 compatibilitylet 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.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.
Comments
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;
}
1 Comment
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);
}
Comments
Basically, a function like input() that exists in Python is not available in NodeJs, on the other hand, there is no clear and simple method to get data from the input.
But in general, this goal can be achieved in two ways:
- Using internal modules available in NodeJs.
This method requires a lot of configuration, so for someone new to NodeJs, it may be too complicated and you may not get the result you want.
- In the second method, it is better to use external modules (packages).
In this way, the complications of this work are minimized and you can reach this goal very easily.
For the second way, there are many packages, one of them is Softio, which has the same methods you mentioned.
To use Softio, just follow the instructions below step by step:
- First you need to install this package. Just run the following command in your project path:
npm install softio
There is no need to worry, when you have installed Node Js, you have also installed npm and you can run the above command.
- Then it is enough to write the following code to get the data from user:
const Console = require( 'softio' );
const name = Console.In.input( 'Enter your name: ' );
Console.Out.writeln( `Welcome ${name}.` );
You can easily read this data from the input like this.
Comments
import { createInterface } from "node:readline/promises";
async function input(prompt: string): Promise<string> {
const rl = createInterface(process.stdin, process.stdout)
const answ = await rl.question(prompt)
rl.close()
return answ
}
const name = await input("what's your name: ")
console.log("your name is", name)