900

Is there a method for printing to the console without a trailing newline? The console object documentation doesn't say anything regarding that:

console.log()

Prints to stdout with newline. This function can take multiple arguments in a printf()-like way. Example:

console.log('count: %d', count);

If formating elements are not found in the first string then util.inspect is used on each argument.

Community
  • 1
  • 1
Evan Carroll
  • 78,363
  • 46
  • 261
  • 468

9 Answers9

1384

You can use process.stdout.write():

process.stdout.write("hello: ");

See the docs for details.

Akseli Palén
  • 27,244
  • 10
  • 65
  • 75
onteria_
  • 68,181
  • 7
  • 71
  • 64
504

Also, if you want to overwrite messages in the same line, for instance in a countdown, you could add \r at the end of the string.

process.stdout.write("Downloading " + data.length + " bytes\r");
Yoav Kadosh
  • 4,807
  • 4
  • 39
  • 56
defvol
  • 14,392
  • 2
  • 22
  • 32
  • 34
    Although not the answer to the question, this is an amazing answer. Can't wait to try. – longda Jun 14 '13 at 21:18
  • 10
    This does *not* work on Windows for me. But works great on non-dows. – chowey Sep 01 '13 at 06:50
  • 52
    For Windows, you can use the equivalent code '\033[0G', as in: `process.stdout.write("Downloading " + data.length + " bytes\033[0G");` – GarciadelCastillo Apr 07 '14 at 15:13
  • 26
    To make the [ansi escape code](https://en.wikipedia.org/wiki/ANSI_escape_code) given above in a comment by @GarciadelCastillo to work in strict mode, replace the octal literal `\033` with the hex literal `\x1b` like this: `\x1b[0G`. (that works with both strict and non-strict code) – some Sep 22 '15 at 02:10
  • 15
    Just put the \r at the beginning rather than at the end of the string to make it work in Windows. – daremkd Feb 18 '16 at 11:05
  • 3
    This is great but how do you make it clear the contents of the line first? `.write("goodbye\r")` followed by `.write("hi\r")` results in `hiodbye` – oooyaya Jan 18 '17 at 13:55
  • 1
    You could first write spaces, for instance you could write `''.padEnd(str.length)` where str is your original string to overwrite, then do your `hello`. – Dan Dart Jul 24 '17 at 17:04
  • 1
    With ANSI escape codes as mentioned above, you can clear the line with `.write("\x1b[0G\x1b[K");`. Or without changing cursor position `.write("\x1b[2K")`. – dewey Feb 01 '18 at 19:46
  • 2
    This didn't work for me. I used: `process.stdout.clearLine(); process.stdout.cursorTo(0);`. I'm not certain if using the carriage return is a hack, but [`clearLine()`](https://nodejs.org/dist/latest-v15.x/docs/api/tty.html#tty_writestream_clearline_dir_callback) and [`cursorTo()`](https://nodejs.org/dist/latest-v15.x/docs/api/tty.html#tty_writestream_cursorto_x_y_callback) are found within the [node.js documentation](https://nodejs.org/en/docs/) – Dave F Apr 07 '21 at 01:56
  • 1
    using @DaveF indication, I get this working ```process.stdout.clearLine(); process.stdout.cursorTo(0); process.stdout.write("Downloading " + i + " bytes\r")``` – Antoine Weber Jul 27 '21 at 09:09
39

As an expansion/enhancement to the brilliant addition made by @rodowi above regarding being able to overwrite a row:

process.stdout.write("Downloading " + data.length + " bytes\r");

Should you not want the terminal cursor to be located at the first character, as I saw in my code, the consider doing the following:

let dots = ''
process.stdout.write(`Loading `)

let tmrID = setInterval(() => {
  dots += '.'
  process.stdout.write(`\rLoading ${dots}`)
}, 1000)

setTimeout(() => {
  clearInterval(tmrID)
  console.log(`\rLoaded in [3500 ms]`)
}, 3500)

By placing the \r in front of the next print statement the cursor is reset just before the replacing string overwrites the previous.

mraxus
  • 1,377
  • 1
  • 15
  • 23
31

In Windows console (Linux, too), you should replace '\r' with its equivalent code \033[0G:

process.stdout.write('ok\033[0G');

This uses a VT220 terminal escape sequence to send the cursor to the first column.

Malekai
  • 4,765
  • 5
  • 25
  • 60
Yan Te
  • 411
  • 4
  • 3
  • 2
    How would you go back up multiple lines instead of just the current line? The *top* program seems to be able to override my entire buffer while it's running and restores what was there when it's done. Anyone know how it does this? http://i.imgur.com/AtCmEjn.gif – CatDadCode Feb 05 '15 at 03:58
  • I believe it probably uses something like one of these: https://github.com/mscdex/node-ncurses https://github.com/chjj/blessed – Brandon Apr 20 '15 at 04:09
  • 1
    It works but I get the cursor as well like `[\] 39` and the cursor is highlighted on the first char: `var spinner = '|/-\\'.split('');process.stdout.write("["+this.randomElement(spinner)+"] "+message+"\033[0G");` – loretoparisi Feb 10 '16 at 11:56
  • 1
    @Chev Top is special, not something you can write with ANSI escape codes. It does, indeed, use ncurses which is why you will not find it on embedded systems which do not have large C libs – cat May 05 '16 at 19:40
  • 2
    @Chev: Most people will dissuade you from playing with hardcoded escape sequences due to their own FUD, but almost everyone uses VT100 now, so compatibility is not really an issue any more. The functionality you are referring to is "alternate screen" behavior. A basic intro can be found in `man console_codes` (on Linux or online) and my favorite reference is http://www2.phys.canterbury.ac.nz/dept/docs/manuals/unix/DEC_4.0e_Docs/HTML/MAN/MAN5/0036____.HTM (99% of its contents still work). Only caveat: Be prepared to test any experiments on several different terminals before deploying widely. – i336_ May 28 '17 at 12:50
  • This is not work in strict mode because octal escapes are deprecated; start escape sequences with `\u001b` (instead of `\033`). – thomasfuchs May 29 '23 at 23:45
19

There seem to be many answers suggesting:

process.stdout.write

Error logs should be emitted on:

process.stderr

Instead use:

console.error

For anyone who is wonder why process.stdout.write('\033[0G'); wasn't doing anything it's because stdout is buffered and you need to wait for drain event (more info).

If write returns false it will fire a drain event.

Malekai
  • 4,765
  • 5
  • 25
  • 60
Ahmed Masud
  • 21,655
  • 3
  • 33
  • 58
12

util.print can be used also. Read: http://nodejs.org/api/util.html#util_util_print

util.print([...])# A synchronous output function. Will block the process, cast each argument to a string then output to stdout. Does not place newlines after each argument.

An example:

// get total length
var len = parseInt(response.headers['content-length'], 10);
var cur = 0;

// handle the response
response.on('data', function(chunk) {
  cur += chunk.length;
  util.print("Downloading " + (100.0 * cur / len).toFixed(2) + "% " + cur + " bytes\r");
});
douyw
  • 4,034
  • 1
  • 30
  • 28
8

None of these solutions work for me, process.stdout.write('ok\033[0G') and just using '\r' just create a new line but don't overwrite on Mac OSX 10.9.2.

EDIT: I had to use this to replace the current line:

process.stdout.write('\033[0G');
process.stdout.write('newstuff');
Malekai
  • 4,765
  • 5
  • 25
  • 60
Tyguy7
  • 573
  • 8
  • 15
5

I got the following error when using strict mode:

Node error: "Octal literals are not allowed in strict mode."

The following solution works (source):

process.stdout.write("received: " + bytesReceived + "\x1B[0G");
Malekai
  • 4,765
  • 5
  • 25
  • 60
blablabla
  • 1,468
  • 15
  • 17
2

If you want that to work both in Linux and Windows, strict mode and non strict mode, and to completely clear the line every time you print, you can use

const str = 'Hi there'
process.stdout.write(str.padEnd(50) + '\x1b[0G')
João Pimentel Ferreira
  • 14,289
  • 10
  • 80
  • 109