573

This seems like a solved problem but I am unable to find a solution for it.

Basically, I read a JSON file, change a key, and write back the new JSON to the same file. All works, but I loose the JSON formatting.So, instead of:

{
  name:'test',
  version:'1.0'
}

I get

{name:'test',version:'1.1'}

Is there a way in Node.js to write well formatted JSON to file ?

Ben
  • 54,723
  • 49
  • 178
  • 224
Rajat
  • 32,970
  • 17
  • 67
  • 87
  • `JSON.stringify` chokes on cyclic objects, and `util.inspect` doesn't produce valid json. :\ I found no [native] solution to pretty printing JSON in NodeJS – ThorSummoner Jan 04 '17 at 00:47
  • 1
    @ThorSummoner: That is a problem with JSON, not with Node—JSON does not natively support cyclic references. There is a solution [here, in another question](https://stackoverflow.com/a/9382383/104184). – Sasha Chedygov Mar 22 '18 at 21:46

8 Answers8

1094

JSON.stringify's third parameter defines white-space insertion for pretty-printing. It can be a string or a number (number of spaces). Node can write to your filesystem with fs. Example:

var fs = require('fs');

fs.writeFile('test.json', JSON.stringify({ a:1, b:2, c:3 }, null, 4));
/* test.json:
{
     "a": 1,
     "b": 2,
     "c": 3,
}
*/

See the JSON.stringify() docs at MDN, Node fs docs

worc
  • 3,654
  • 3
  • 31
  • 35
Ricardo Tomasi
  • 34,573
  • 2
  • 55
  • 66
  • 28
    Note : instead of 4, use `"\t"` if you want tabs. – Jeremy Thille Apr 01 '20 at 04:36
  • In latest nodejs you need to provide a callback function as third parameter, see this answer: https://stackoverflow.com/a/11677276/675065 – Alp Apr 23 '20 at 07:30
  • @Alp means the third parameter of `fs.writeFile`; you don't actually have to use the callback if the write is the last command in your script. You only need the callback if you want to do something after `writeFile`, other than exit the process. – jcollum Sep 29 '20 at 23:18
240

I think this might be useful... I love example code :)

var fs = require('fs');

var myData = {
  name:'test',
  version:'1.0'
}

var outputFilename = '/tmp/my.json';

fs.writeFile(outputFilename, JSON.stringify(myData, null, 4), function(err) {
    if(err) {
      console.log(err);
    } else {
      console.log("JSON saved to " + outputFilename);
    }
}); 
Alexey B.
  • 11,965
  • 2
  • 49
  • 73
nym
  • 430
  • 1
  • 8
  • 21
120

If you just want to pretty print an object and not export it as valid JSON you can use console.dir().

It uses syntax-highlighting, smart indentation, removes quotes from keys and just makes the output as pretty as it gets.

const jsonString = `{"name":"John","color":"green",
                     "smoker":false,"id":7,"city":"Berlin"}`
const object = JSON.parse(jsonString)

console.dir(object, {depth: null, colors: true})

Screenshot of logged object

Under the hood it is a shortcut for console.log(util.inspect(…)). The only difference is that it bypasses any custom inspect() function defined on an object.

adius
  • 13,685
  • 7
  • 45
  • 46
53

If you don't want to store this anywhere, but just view the object for debugging purposes.

console.log(JSON.stringify(object, null, "  "));

You can change the third parameter to adjust the indentation.

Sanket Berde
  • 6,555
  • 4
  • 35
  • 39
35

I know this is old question. But maybe this can help you

JSON string

var jsonStr = '{ "bool": true, "number": 123, "string": "foo bar" }';

Pretty Print JSON

JSON.stringify(JSON.parse(jsonStr), null, 2);

Minify JSON

JSON.stringify(JSON.parse(jsonStr));
illvart
  • 847
  • 9
  • 10
29

what about this?

console.table(object)

sample

Samuel Philipp
  • 10,631
  • 12
  • 36
  • 56
  • this is a good solution for small datasets, but for large, complex, deeply nested objects it's essentially impossible to read with all the line wrapping. there might be a solution to that too I suppose. – Matt Korostoff Dec 06 '21 at 19:59
4

Another workaround would be to make use of prettier to format the JSON. The example below is using 'json' parser but it could also use 'json5', see list of valid parsers.

const prettier = require("prettier");
console.log(prettier.format(JSON.stringify(object),{ semi: false, parser: "json" }));
jkonst
  • 433
  • 6
  • 20
-1

if prettify is name value pairs on new lines then specifying number of spaces in stringify didn't work for me the only thing that worked for me was

await fs.promises.writeFile('testdataattr.json',JSON.stringify(datatofile, null,'\r\n'),'utf8') ;
GMC
  • 1
  • 1