How to get password from input using node.js? Which means you should not output password entered in console.
5 Answers
You can use the read
module (disclosure: written by me) for this:
In your shell:
npm install read
Then in your JS:
var read = require('read')
read({ prompt: 'Password: ', silent: true }, function(er, password) {
console.log('Your password is: %s', password)
})
-
2https://github.com/isaacs/read - Had some trouble googling for this module so, I'm dropping a link to it here for your convenience. – paulolc Feb 19 '13 at 00:38
-
2Is there a synchronous version? – mpen Sep 10 '13 at 23:55
-
1@Mark: How could there be? stdin is a stream and fires events. Events cannot be processed if a function is waiting to return. – josh3736 Oct 23 '13 at 21:20
-
7@josh3736: I don't know, perhaps in the same way that `readFileSync` works?? – mpen Oct 23 '13 at 22:30
-
@josh3736: not sync, but I use module async.forEachSeries or async.forever to ask consecutive input questions via async functions. – bryanmac Dec 10 '14 at 12:27
-
when i try to debug a script that runs into this code I can't figure out what to type to let it actually enter my password – Michael Jul 11 '16 at 23:19
-
@isaacs - how do I setup the launch.json to provide the input args when debugging? – cosbor11 Jan 28 '20 at 22:20
-
@mpen best workaround today to avoid the callback is to use `async`/`await` BTW: https://stackoverflow.com/a/71868483/895245 – Ciro Santilli OurBigBook.com Apr 14 '22 at 08:15
Update 2015 Dec 13: readline
has replaced process.stdin
and node_stdio was removed from Node 0.5.10.
var BACKSPACE = String.fromCharCode(127);
// Probably should use readline
// https://nodejs.org/api/readline.html
function getPassword(prompt, callback) {
if (prompt) {
process.stdout.write(prompt);
}
var stdin = process.stdin;
stdin.resume();
stdin.setRawMode(true);
stdin.resume();
stdin.setEncoding('utf8');
var password = '';
stdin.on('data', function (ch) {
ch = ch.toString('utf8');
switch (ch) {
case "\n":
case "\r":
case "\u0004":
// They've finished typing their password
process.stdout.write('\n');
stdin.setRawMode(false);
stdin.pause();
callback(false, password);
break;
case "\u0003":
// Ctrl-C
callback(true);
break;
case BACKSPACE:
password = password.slice(0, password.length - 1);
process.stdout.clearLine();
process.stdout.cursorTo(0);
process.stdout.write(prompt);
process.stdout.write(password.split('').map(function () {
return '*';
}).join(''));
break;
default:
// More passsword characters
process.stdout.write('*');
password += ch;
break;
}
});
}
getPassword('Password: ', (ok, password) => { console.log([ok, password]) } );

- 347,512
- 102
- 1,199
- 985

- 110,530
- 99
- 389
- 494
-
You can't verify value. If you press backspace or other touch who isn't alphanumeric. – user2226755 Jun 04 '14 at 12:10
-
To do this I found this excellent Google Group post
Which contains the following snippet:
var stdin = process.openStdin()
, stdio = process.binding("stdio")
stdio.setRawMode()
var password = ""
stdin.on("data", function (c) {
c = c + ""
switch (c) {
case "\n": case "\r": case "\u0004":
stdio.setRawMode(false)
console.log("you entered: "+password)
stdin.pause()
break
case "\u0003":
process.exit()
break
default:
password += c
break
}
})

- 60,935
- 33
- 147
- 186
-
Note process.binding("stdio") no longer works in current versions of node – mikemaccana Apr 27 '12 at 20:43
Here is my tweaked version of nailer's from above, updated to get a callback and for node 0.8 usage:
/**
* Get a password from stdin.
*
* Adapted from <http://stackoverflow.com/a/10357818/122384>.
*
* @param prompt {String} Optional prompt. Default 'Password: '.
* @param callback {Function} `function (cancelled, password)` where
* `cancelled` is true if the user aborted (Ctrl+C).
*
* Limitations: Not sure if backspace is handled properly.
*/
function getPassword(prompt, callback) {
if (callback === undefined) {
callback = prompt;
prompt = undefined;
}
if (prompt === undefined) {
prompt = 'Password: ';
}
if (prompt) {
process.stdout.write(prompt);
}
var stdin = process.stdin;
stdin.resume();
stdin.setRawMode(true);
stdin.resume();
stdin.setEncoding('utf8');
var password = '';
stdin.on('data', function (ch) {
ch = ch + "";
switch (ch) {
case "\n":
case "\r":
case "\u0004":
// They've finished typing their password
process.stdout.write('\n');
stdin.setRawMode(false);
stdin.pause();
callback(false, password);
break;
case "\u0003":
// Ctrl-C
callback(true);
break;
default:
// More passsword characters
process.stdout.write('*');
password += ch;
break;
}
});
}

- 199
- 1
- 6
-
You can handle backspace with an extra case statement for `"u007F"`. If the password so far is non-empty, you can use `process.stdout.write('\033[<1>D')` to move the cursor back one column; after that you can write a space, then move back again. – Jun 26 '15 at 08:02
-
I updated this to work with backspace and merged it with the original accepted answer and added a link to a repo that I plan to continue to improve. – coolaj86 Dec 13 '15 at 10:46
How to use read
without a callback
With async
/await
, we can get rid of the annoying callback with the following standard pattern:
const readCb = require('read')
async function read(opts) {
return new Promise((resolve, reject) => {
readCb(opts, (err, line) => {
if (err) {
reject(err)
} else {
resolve(line)
}
})
})
}
;(async () => {
const password = await read({ prompt: 'Password: ', silent: true })
console.log(password)
})()
The annoyance is that then you have to propagate async/await to the entire call stack, but it is generally the way to go, as it clearly marks what is async or not.
Tested on "read": "1.0.7", Node.js v14.17.0.
TODO how to prevent EAGAIN error if you try to use stdin again later with fs.readFileSync(0)
?
Both read
and https://stackoverflow.com/a/10357818/895245 cause future attempts to read from stdin with fs.readFileSync(0)
to break with EAGAIN. Not sure how to fix that. Reproduction:
const fs = require('fs')
const readCb = require('read')
async function read(opts) {
return new Promise((resolve, reject) => {
readCb(opts, (err, line) => {
resolve([err, line])
})
})
}
;(async () => {
const [err, password] = await read({ prompt: 'Password: ', silent: true })
console.log(password)
console.log(fs.readFileSync(0).toString())
})()
or:
#!/usr/bin/env node
const fs = require('fs')
var BACKSPACE = String.fromCharCode(127);
// Probably should use readline
// https://nodejs.org/api/readline.html
function getPassword(prompt, callback) {
if (prompt) {
process.stdout.write(prompt);
}
var stdin = process.stdin;
stdin.resume();
stdin.setRawMode(true);
stdin.resume();
stdin.setEncoding('utf8');
var password = '';
stdin.on('data', function (ch) {
ch = ch.toString('utf8');
switch (ch) {
case "\n":
case "\r":
case "\u0004":
// They've finished typing their password
process.stdout.write('\n');
stdin.setRawMode(false);
stdin.pause();
callback(false, password);
break;
case "\u0003":
// Ctrl-C
callback(true);
break;
case BACKSPACE:
password = password.slice(0, password.length - 1);
process.stdout.clearLine();
process.stdout.cursorTo(0);
process.stdout.write(prompt);
process.stdout.write(password.split('').map(function () {
return '*';
}).join(''));
break;
default:
// More passsword characters
process.stdout.write('*');
password += ch;
break;
}
});
}
async function read(opts) {
return new Promise((resolve, reject) => {
getPassword(opts, (err, line) => {
resolve([err, line])
})
})
}
;(async () => {
const [err, password] = await read('Password: ')
console.log(password)
console.log(fs.readFileSync(0).toString())
})()
Error:
fs.js:614
handleErrorFromBinding(ctx);
^
Error: EAGAIN: resource temporarily unavailable, read
at Object.readSync (fs.js:614:3)
at tryReadSync (fs.js:383:20)
at Object.readFileSync (fs.js:420:19)
at /home/ciro/test/main.js:70:18
at processTicksAndRejections (internal/process/task_queues.js:95:5) {
errno: -11,
syscall: 'read',
code: 'EAGAIN'
}
Asked at: https://github.com/npm/read/issues/39

- 347,512
- 102
- 1,199
- 985
-
1You could `reject()` if there's an error instead of returning a tuple. Your error might be from forgetting to close some pipe. e.g. you have to `close()` readline interfaces ([eg](https://stackoverflow.com/a/50890409/65387)) – mpen Apr 16 '22 at 01:39