452

What is the difference between "process.stdout.write" and "console.log" in node.js?

EDIT: Using console.log for a variable showed a lot of unreadable characters while using process.stdout.write showed an object.

Why is that?

MPelletier
  • 16,256
  • 15
  • 86
  • 137
ajsie
  • 77,632
  • 106
  • 276
  • 381
  • 6
    Can you provide an example? console.log() calls process.stdout.write with formatted output. See format() in console.js for the implementation. – TK-421 Feb 12 '11 at 11:47

11 Answers11

472

console.log() calls process.stdout.write with formatted output. See format() in console.js for the implementation.

Currently (v0.10.ish):

Console.prototype.log = function() {
  this._stdout.write(util.format.apply(this, arguments) + '\n');
};
TK-421
  • 10,598
  • 3
  • 38
  • 34
  • 63
    Also worth mentioning that `console.log()` appears to add a newline – jchook Apr 12 '18 at 01:56
  • 6
    `console.log()` **also** broadcasts to [debugging clients](https://nodejs.org/en/docs/guides/debugging-getting-started/). To broadcast to debugging clients without printing to stdio, you can use [`require('inspector').console.log()`](https://nodejs.org/api/inspector.html#inspector_inspector_console). – Niklas E. Oct 26 '20 at 19:28
  • 1
    The main difference is in the intent: `console.log`(debug/warn/whatever) is for **logging** in some **developer console** (could be browser based like chrome dev tools, or simply stdout in case of nodejs). The purpose of `process.stdout` is for the code to write to the terminal, which for console applications is typically the process output, and not just logging. The fact that they happen to relate to each other is a fortuitous accident. – Christian Jul 08 '23 at 22:13
180

Looking at the Node docs apparently console.log is just process.stdout.write with a line-break at the end:

console.log = function (d) {
  process.stdout.write(d + '\n');
};

Source: http://nodejs.org/docs/v0.3.1/api/process.html#process.stdout

Mauvis Ledford
  • 40,827
  • 17
  • 81
  • 86
  • 38
    For people coming along around later, please note that v0.3.1 was a long time ago and things have changed since then. :) – Brendan Feb 25 '15 at 04:17
  • 8
    ...nope. Just looked at v0.9.9 docs and console.log is still just an alias to process.stdout.write with a linebreak. Please do your research before commenting. http://nodejs.org/docs/v0.9.9/api/process.html#process.stdout – Mauvis Ledford Feb 25 '15 at 17:53
  • 19
    1) v0.9.9 is two years old 2) that documentation is incorrect, [as per v0.9.9 the format is interpolated through util](https://github.com/joyent/node/blob/v0.9.9-release/lib/console.js#L52) – Brendan Feb 26 '15 at 05:21
  • 6
    Actually, it seems that that documentation has never been updated and is still around (DRY anybody?). I'll be submitting a PR to fix that, thanks for notifying me of that issue :) – Brendan Feb 26 '15 at 05:25
  • Also, https://nodejs.org/docs/latest/api/console.html#console_console_log_data_args and https://nodejs.org/docs/latest/api/util.html#util_util_format_format_args. – Charles Wood Dec 29 '17 at 19:50
104

I know this is a very old question but I didn't see anybody talking about the main difference between process.stdout.write and console.log and I just want to mention it.

As Mauvis Leford and TK-421 pointed out, the console.log adds a line-break character at the end of the line (\n) but that's not all what it does.

The code has not changed since at least 0.10.X version and now we have a a 5.X version.

Here is the code:

Console.prototype.log = function() {
  this._stdout.write(util.format.apply(this, arguments) + '\n');
};

As you can see, there is a part that says .apply(this, arguments) and that makes a big difference on functionality. It is easier to explain that with examples:

process.stdout.write has a very basic functionality, you can just write something in there, like this:

process.stdout.write("Hello World\n"); 

If you don't put the break line at the end you will get a weird character after your string, something like this:

process.stdout.write("Hello World"); //Hello World% 

(I think that means something like "the end of the program", so you will see it only if you process.stdout.write was used at the end of your file and you didn't add the break line)

On the other hand, console.log can do more.

  1. You can use it in the same way

    console.log("Hello World"); //You don't need the break line here because it was already formated and also that weird character did disappear

  2. You can write more than one string

    console.log("Hello", "World");

  3. You can make associations

    console.log("Hello %s", "World") //Useful when "World" is inside a variable

An that's it, that added functionality is given thanks to the util.format.apply part (I could talk a lot about what exactly this does but you get my point, you can read more here).

I hope somebody find this information useful.

Community
  • 1
  • 1
Gepser Hoil
  • 3,998
  • 4
  • 24
  • 34
  • It would be very helpful also if you explained how to use `stdout.write` and avoid getting `%` – Muhammad Hamada Jan 17 '17 at 16:07
  • I solved the problem of getting `%` at the end by simply calling `process.stdout.write('\n');` at the end of my loop (if you have for example) – Muhammad Hamada Jan 17 '17 at 16:09
  • 11
    The `%` is just the shell's way of saying there's no newline at the end of the file. – Dave Newton Jun 13 '19 at 02:08
  • 7
    @DaveNewton your point is important, because it means that if you are redirecting the output of your program to a file, for example, you will not get that `%` in the file – mr.mams Apr 03 '20 at 10:30
  • Great explain. So 2 things: console.log supports arguments joining and % at the end. – jiajianrong Nov 29 '22 at 12:50
42

One big difference that hasn't been mentioned is that process.stdout only takes strings as arguments (can also be piped streams), while console.log takes any Javascript data type.

e.g:

// ok
console.log(null)
console.log(undefined)
console.log('hi')
console.log(1)
console.log([1])
console.log({one:1})
console.log(true)
console.log(Symbol('mysymbol'))

// any other data type passed as param will throw a TypeError
process.stdout.write('1')

// can also pipe a readable stream (assuming `file.txt` exists)
const fs = require('fs')
fs.createReadStream('file.txt').pipe(process.stdout)
myconode
  • 2,518
  • 1
  • 26
  • 28
31

Another important difference in this context would with process.stdout.clearLine() and process.stdout.cursorTo(0).

This would be useful if you want to show percentage of download or processing in the only one line. If you use clearLine(), cursorTo() with console.log() it doesn't work because it also append \n to the text. Just try out this example:

var totalTime = 5000;
var waitInterval = totalTime / 10;
var currentInterval = 0;

function showPercentage(percentage){
    process.stdout.clearLine()
    process.stdout.cursorTo(0)
    console.log(`Processing ${percentage}%...` ) // Replace this line with process.stdout.write(`Processing ${percentage}%...`)
}

var interval = setInterval(function(){
    currentInterval += waitInterval
    showPercentage((currentInterval / totalTime) * 100)
}, waitInterval)

setTimeout(function(){
    clearInterval(interval)
}, totalTime + 100)
Ravi Makwana
  • 2,782
  • 1
  • 29
  • 41
saikirann
  • 441
  • 4
  • 5
12

I've just noticed something while researching this after getting help with https.request for post method. Thought I share some input to help understand.

process.stdout.write doesn't add a new line while console.log does, like others had mentioned. But there's also this which is easier to explain with examples.

var req = https.request(options, (res) => {
    res.on('data', (d) => {
        process.stdout.write(d);
        console.log(d)
    });
});

process.stdout.write(d); will print the data properly without a new line. However console.log(d) will print a new line but the data won't show correctly, giving this <Buffer 12 34 56... for example.

To make console.log(d) show the information correctly, I would have to do this.

var req = https.request(options, (res) => {
    var dataQueue = "";    
    res.on("data", function (d) {
        dataQueue += d;
    });
    res.on("end", function () {
        console.log(dataQueue);
    });
});

So basically:

  • process.stdout.write continuously prints the information as the data being retrieved and doesn't add a new line.

  • console.log prints the information what was obtained at the point of retrieval and adds a new line.

That's the best way I can explain it.

Nova
  • 2,000
  • 3
  • 14
  • 24
2

The Simple Difference is: console.log() methods automatically append new line character. It means if we are looping through and printing the result, each result get printed in new line.

process.stdout.write() methods don't append new line character. useful for printing patterns.

2

The answers here are great. The following expands on the significance of the console.log formatting function. One of the features of formatting not yet mentioned are group levels, which log will honor, but stdout will not.

console.log('Begin...')

console.group()
console.log('Line 2 (console.log)')
process.stdout.write('Line 3 (process.stdout)\n')
console.log('Line 4 (console.log)')
process.stdout.write('Line 5 (process.stdout)') // no newline
console.groupEnd()

console.log('...done')

Output:

Begin...
  Line 2 (console.log)
Line 3 (process.stdout)
  Line 4 (console.log)
Line 5 (process.stdout)...done

Notice stdout does not honor the console.group formatting and always writes to the beginning of the line, where as console.log honors the grouping and indents appropriately.


The same performed only with log statements (and an additional group):

console.log('Begin...')

console.group()
console.log('Line 2 (console.log)')
console.log('Line 3 (console.log)')
console.log('Line 4 (console.log)')
console.log('Line 5 (console.log)')
console.group()
console.log('Line 6 (console.log)')
console.log('Line 7 (console.log)')
console.groupEnd()
console.groupEnd()

console.log('...done')

Output:

Begin...
  Line 2 (console.log)
  Line 3 (console.log)
  Line 4 (console.log)
  Line 5 (console.log)
    Line 6 (console.log)
    Line 7 (console.log)
...done
Mike
  • 94
  • 4
1

Console.log implement process.sdout.write, process.sdout.write is a buffer/stream that will directly output in your console.

According to my puglin serverline : console = new Console(consoleOptions) you can rewrite Console class with your own readline system.

You can see code source of console.log:


See more :

user2226755
  • 12,494
  • 5
  • 50
  • 73
-1

console.log() adds tons of things and a new line every time you call it

process.stdout.write() is just plain text, no formatting

That's what I was taught at least

-3

For those who like Deno, I was able to achieve this by using the following ANSI Escape Sequences in conjunction with Deno's version of process.stdout.write.

ESC[2K  clears entire line
ESC[#G  moves cursor to column #

Code

/*
    Console.log() to the same line
    Supported in Deno 1.8.1
*/

const myTextEncoder : TextEncoder = new TextEncoder();

let counter : number = 0;

while(counter < 100000) {

  // ESC[2K clears entire line
  await Deno.stdout.write(myTextEncoder.encode(`\x1b[2K`));
  // ESC[#G moves cursor to column #
  await Deno.stdout.write(myTextEncoder.encode(`\x1b[0G`));
  // OUTPUT incremented counter
  await Deno.stdout.write(myTextEncoder.encode(`COUNTER: ${counter++}`));

}
suchislife
  • 4,251
  • 10
  • 47
  • 78