Back to Blog

    How to Prettify JSON in Node.js: 5 Methods with Examples (2025)

    Prettifying JSON in Node.js is something every developer does — whether you're debugging API responses, writing configuration files, or building developer tools. In this guide, you'll learn how to prettify JSON in Node.js using five different methods, complete with real code examples, common pitfalls, and tips for handling large files and complex nested structures.

    What Does “Prettify JSON” Mean?

    JSON (JavaScript Object Notation) can be represented in two forms: minified and prettified. Minified JSON strips out all whitespace and newlines, making the payload as compact as possible for network transfer. Prettified (or “beautified”) JSON, on the other hand, adds indentation, line breaks, and spacing so humans can easily read and understand the structure.

    Here is the same data in both forms side by side:

    // Minified JSON (hard to read at a glance)
    {"name":"Alice","age":30,"address":{"city":"New York","zip":"10001"},"hobbies":["reading","coding"]}
    
    // Prettified JSON (easy to scan and debug)
    {
      "name": "Alice",
      "age": 30,
      "address": {
        "city": "New York",
        "zip": "10001"
      },
      "hobbies": [
        "reading",
        "coding"
      ]
    }

    Prettified JSON matters enormously for developer productivity. When you're inspecting API responses, reading configuration files, or writing log output for debugging, a well-indented structure lets you spot errors instantly. Minified JSON is ideal for production payloads where bandwidth counts; prettified JSON is ideal for everything else — config files, source-controlled JSON, logs, and development responses.

    Method 1: JSON.stringify() with the Indent Parameter

    The simplest and most universally-used approach is the built-in JSON.stringify() method. Most developers know the first parameter, but the method actually accepts three:

    • value — The JavaScript object or value to convert to JSON.
    • replacer — An optional function or array to filter which keys are included. Pass null to include all keys.
    • space — A number (of spaces) or a string used as indentation. This is what turns minified JSON into prettified JSON.
    // Basic usage — 2-space indentation (most common for config files)
    const user = {
      name: "Alice",
      age: 30,
      roles: ["admin", "editor"],
    };
    
    const prettyJson2 = JSON.stringify(user, null, 2);
    console.log(prettyJson2);
    /* Output:
    {
      "name": "Alice",
      "age": 30,
      "roles": [
        "admin",
        "editor"
      ]
    }
    */
    
    // 4-space indentation (common in many style guides)
    const prettyJson4 = JSON.stringify(user, null, 4);
    console.log(prettyJson4);
    /* Output:
    {
        "name": "Alice",
        "age": 30,
        "roles": [
            "admin",
            "editor"
        ]
    }
    */
    
    // Tab indentation (useful when you want literal tabs)
    const prettyJsonTab = JSON.stringify(user, null, "\t");
    console.log(prettyJsonTab);

    You can also use the replacer parameter to selectively include keys — handy when you want to prettify only part of an object or exclude sensitive fields:

    const userData = {
      name: "Bob",
      password: "s3cr3t",   // sensitive — we want to exclude this
      email: "bob@example.com",
      age: 25,
    };
    
    // Only include "name" and "email" keys
    const filtered = JSON.stringify(userData, ["name", "email"], 2);
    console.log(filtered);
    /* Output:
    {
      "name": "Bob",
      "email": "bob@example.com"
    }
    */
    
    // Use a replacer function to mask sensitive values
    const masked = JSON.stringify(userData, (key, value) => {
      if (key === "password") return "****";
      return value;
    }, 2);
    console.log(masked);

    Method 2: Prettify a JSON File with the fs Module

    A very common task in Node.js is reading a JSON file from disk, prettifying it, and writing it back. This is useful for formatting configuration files, normalizing data dumps, or preparing files for version control. The built-in fs module makes this straightforward.

    Below is a complete, production-ready Node.js script that reads any JSON file, prettifies it with 2-space indentation, and writes the result back (or to a new output file):

    // prettify-json-file.js
    const fs = require("fs");
    const path = require("path");
    
    /**
     * Reads a JSON file, prettifies it, and writes the result.
     * @param {string} inputPath  - Path to the source JSON file.
     * @param {string} outputPath - Path to write the prettified JSON.
     * @param {number} indent     - Number of spaces for indentation (default: 2).
     */
    function prettifyJsonFile(inputPath, outputPath, indent = 2) {
      try {
        // Read the raw file content
        const raw = fs.readFileSync(inputPath, "utf8");
    
        // Parse it to a JavaScript object (throws on invalid JSON)
        const parsed = JSON.parse(raw);
    
        // Stringify with indentation
        const pretty = JSON.stringify(parsed, null, indent);
    
        // Write the prettified JSON to the output path
        fs.writeFileSync(outputPath, pretty, "utf8");
    
        console.log(`✅ Prettified JSON written to: ${outputPath}`);
      } catch (err) {
        if (err instanceof SyntaxError) {
          console.error("❌ Invalid JSON:", err.message);
        } else {
          console.error("❌ File error:", err.message);
        }
      }
    }
    
    // Usage — prettify in-place or to a new file
    const inputFile = path.join(__dirname, "data.json");
    const outputFile = path.join(__dirname, "data.pretty.json");
    prettifyJsonFile(inputFile, outputFile, 2);

    For asynchronous file handling (preferred in production to avoid blocking the event loop), you can use the promise-based fs.promises API or the fs/promises module:

    // prettify-json-async.mjs  (ES Module syntax)
    import { readFile, writeFile } from "fs/promises";
    import { resolve } from "path";
    
    async function prettifyJsonAsync(inputPath, outputPath, indent = 2) {
      const raw = await readFile(resolve(inputPath), "utf8");
      const pretty = JSON.stringify(JSON.parse(raw), null, indent);
      await writeFile(resolve(outputPath), pretty, "utf8");
      console.log("Done! Prettified JSON saved to:", outputPath);
    }
    
    await prettifyJsonAsync("./input.json", "./output.json");

    Method 3: Pretty-Printing JSON in Express.js

    When building REST APIs with Express.js, you probably use res.json() to send JSON responses. By default, Express sends minified JSON. You can make all responses pretty-printed with a single setting, or apply it selectively via middleware.

    // server.js — Express.js with global pretty-print
    const express = require("express");
    const app = express();
    
    // Set JSON indentation globally for all res.json() calls
    app.set("json spaces", 2);
    
    app.get("/api/user", (req, res) => {
      res.json({
        id: 1,
        name: "Carol",
        email: "carol@example.com",
        roles: ["viewer", "editor"],
      });
    });
    
    app.listen(3000, () => console.log("Server running on port 3000"));
    
    /* GET /api/user now returns:
    {
      "id": 1,
      "name": "Carol",
      "email": "carol@example.com",
      "roles": [
        "viewer",
        "editor"
      ]
    }
    */

    If you only want pretty output during development (not in production where minified is preferred for performance), use an environment check:

    // Pretty-print only in development
    if (process.env.NODE_ENV !== "production") {
      app.set("json spaces", 2);
    }
    
    // Or: allow clients to request pretty output via a query param
    app.use((req, res, next) => {
      if (req.query.pretty === "true") {
        app.set("json spaces", 2);
      } else {
        app.set("json spaces", 0); // minified
      }
      next();
    });

    Method 4: Using the Prettier Library for JSON

    Prettier is the industry-standard code formatter that supports JSON out of the box. It goes beyond simple indentation — it enforces consistent trailing commas, quote styles, and line lengths. This is especially useful in CI/CD pipelines or editor integrations where you want enforced formatting across an entire codebase.

    # Install prettier
    npm install --save-dev prettier
    
    # Format a JSON file directly from the CLI
    npx prettier --write data.json
    
    # Format and output to stdout (without modifying the file)
    npx prettier --parser json data.json

    You can also use the Prettier Node.js API to format JSON programmatically inside your scripts:

    // format-with-prettier.mjs
    import prettier from "prettier";
    import { readFile, writeFile } from "fs/promises";
    
    async function formatJsonWithPrettier(filePath) {
      const raw = await readFile(filePath, "utf8");
    
      // prettier.format returns a Promise<string>
      const formatted = await prettier.format(raw, {
        parser: "json",
        tabWidth: 2,
        printWidth: 80,
      });
    
      await writeFile(filePath, formatted, "utf8");
      console.log(`Formatted ${filePath} with Prettier`);
    }
    
    await formatJsonWithPrettier("./package.json");

    Prettier reads your project's .prettierrc config automatically, so any formatting preferences you have already configured (tab width, trailing commas, etc.) will apply to JSON files as well.

    Method 5: Command Line — node -e and jq

    Sometimes you just need a quick one-liner in the terminal without writing a script. Both Node.js itself and the popular jq utility are excellent for this.

    # Prettify a JSON file using Node.js one-liner (Unix/macOS)
    node -e "
      const fs = require('fs');
      const data = JSON.parse(fs.readFileSync('data.json', 'utf8'));
      console.log(JSON.stringify(data, null, 2));
    " > data.pretty.json
    
    # Pipe minified JSON from curl and prettify it (Unix/macOS)
    curl -s https://api.example.com/users | node -e "
      let d=''; process.stdin.on('data',c=>d+=c);
      process.stdin.on('end',()=>console.log(JSON.stringify(JSON.parse(d),null,2)));
    "
    
    # Using jq — the gold standard for CLI JSON prettification
    # Install: brew install jq (macOS) or apt install jq (Linux)
    jq . data.json                        # prettify file
    curl -s https://api.example.com | jq .  # prettify API response
    
    # jq also lets you query and transform in one step
    jq '.users[] | select(.active == true)' users.json
    
    # Windows PowerShell equivalent using ConvertFrom-Json + ConvertTo-Json
    Get-Content data.json | ConvertFrom-Json | ConvertTo-Json -Depth 10

    Prettifying Nested & Complex JSON

    JSON.stringify handles nesting automatically — there's no depth limit by default. However, deeply nested structures or arrays of objects deserve extra attention to confirm the output is truly readable. Here is a realistic before/after example with an e-commerce order payload:

    const order = {
      orderId: "ORD-20250605-9821",
      customer: { id: 42, name: "Dave", email: "dave@shop.com" },
      items: [
        { sku: "WIDGET-A", qty: 2, price: 9.99 },
        { sku: "GADGET-B", qty: 1, price: 49.99 },
      ],
      shipping: { method: "express", address: { line1: "123 Main St", city: "Austin", state: "TX", zip: "78701" } },
      total: 69.97,
      paid: true,
    };
    
    // Before — minified (what you might receive from an API or database)
    const minified = JSON.stringify(order);
    // {"orderId":"ORD-20250605-9821","customer":{"id":42,"name":"Dave",...},...}
    
    // After — prettified (what you want for debugging or config storage)
    const pretty = JSON.stringify(order, null, 2);
    console.log(pretty);
    
    /* Output:
    {
      "orderId": "ORD-20250605-9821",
      "customer": {
        "id": 42,
        "name": "Dave",
        "email": "dave@shop.com"
      },
      "items": [
        {
          "sku": "WIDGET-A",
          "qty": 2,
          "price": 9.99
        },
        {
          "sku": "GADGET-B",
          "qty": 1,
          "price": 49.99
        }
      ],
      "shipping": {
        "method": "express",
        "address": {
          "line1": "123 Main St",
          "city": "Austin",
          "state": "TX",
          "zip": "78701"
        }
      },
      "total": 69.97,
      "paid": true
    }
    */

    Common Mistakes When Formatting JSON in Node.js

    Even experienced developers run into subtle issues when prettifying JSON. Here are the most common pitfalls — and how to fix them.

    1. Circular References

    JSON.stringify will throw a TypeError: Converting circular structure to JSON if your object contains circular references (e.g., an object that references itself).

    // ❌ This throws a TypeError
    const obj = { name: "circular" };
    obj.self = obj; // circular reference!
    JSON.stringify(obj, null, 2); // TypeError: Converting circular structure to JSON
    
    // ✅ Fix using a WeakSet-based replacer to skip circular refs
    function safeStringify(value, indent = 2) {
      const seen = new WeakSet();
      return JSON.stringify(value, (key, val) => {
        if (typeof val === "object" && val !== null) {
          if (seen.has(val)) return "[Circular]";
          seen.add(val);
        }
        return val;
      }, indent);
    }
    
    console.log(safeStringify(obj));
    /* Output:
    {
      "name": "circular",
      "self": "[Circular]"
    }
    */

    2. undefined Values and Functions Are Silently Dropped

    JSON.stringify silently omits keys whose values are undefined, Symbol, or a function. This can cause confusion when you expect certain keys to appear in the output.

    // ⚠️ Undefined and function values are dropped silently
    const config = {
      host: "localhost",
      port: 3000,
      secret: undefined,       // ← will be omitted
      getUrl: () => "...",     // ← will be omitted
    };
    
    console.log(JSON.stringify(config, null, 2));
    /* Output — "secret" and "getUrl" are missing:
    {
      "host": "localhost",
      "port": 3000
    }
    */
    
    // ✅ Convert undefined to null to preserve the key
    const safe = JSON.stringify(config, (key, value) => {
      return value === undefined ? null : value;
    }, 2);
    console.log(safe);
    /* Output:
    {
      "host": "localhost",
      "port": 3000,
      "secret": null
    }
    */

    3. BigInt Values Throw an Error

    JavaScript BigInt values are not natively serializable by JSON.stringify and will throw a TypeError: Do not know how to serialize a BigInt.

    // ❌ BigInt throws TypeError
    const data = { id: 9007199254740993n };
    JSON.stringify(data, null, 2); // TypeError: Do not know how to serialize a BigInt
    
    // ✅ Fix: convert BigInt to string in the replacer
    const safeBigInt = JSON.stringify(data, (key, value) => {
      return typeof value === "bigint" ? value.toString() : value;
    }, 2);
    console.log(safeBigInt);
    /* Output:
    {
      "id": "9007199254740993"
    }
    */

    When to Use Online JSON Prettifiers

    Sometimes you don't want to write a script at all. You just need to quickly inspect a JSON blob you received from an API, a webhook payload, or a database export. This is where online JSON prettifiers shine.

    Online tools are ideal when:

    • You need to visually inspect a one-off API response without setting up a script.
    • You're sharing JSON with a colleague and want it formatted for readability.
    • You want syntax validation to quickly catch malformed JSON (missing commas, unquoted keys, etc.).
    • You're on a machine where you can't install Node.js or other tools.
    • You want collapsible tree views to navigate deeply nested structures without scrolling.

    A great online tool will also show you a collapsible tree view, line numbers, error highlighting, and let you copy the formatted output in one click. No installation, no dependencies — just paste and go.

    Performance: Prettify Large JSON Files in Node.js

    For most everyday use cases — configs, API payloads, small data files — JSON.parse + JSON.stringify is fast enough. However, if you're dealing with JSON files in the hundreds of megabytes (database dumps, log files, analytics exports), loading the entire file into memory will be slow and may exhaust the Node.js heap.

    The solution is streaming JSON parsing using a library like JSONStream or stream-json. These tools process JSON token-by-token without loading the full document into memory.

    // Install stream-json for large file processing
    // npm install stream-json
    
    const { createReadStream, createWriteStream } = require("fs");
    const { chain } = require("stream-chain");
    const { parser } = require("stream-json");
    const { streamValues } = require("stream-json/streamers/StreamValues");
    
    // For a JSON array of records — prettify each record individually
    chain([
      createReadStream("large-data.json"),
      parser(),
      streamValues(),
    ]).on("data", ({ key, value }) => {
      // Process one record at a time — memory efficient
      const pretty = JSON.stringify(value, null, 2);
      console.log(pretty);
    });
    
    // For smaller files (< ~50MB): simple approach is still fine
    const fs = require("fs");
    const start = Date.now();
    const data = JSON.parse(fs.readFileSync("medium-data.json", "utf8"));
    const pretty = JSON.stringify(data, null, 2);
    fs.writeFileSync("medium-data.pretty.json", pretty, "utf8");
    console.log(`Done in ${Date.now() - start}ms`);

    As a rule of thumb: files under ~50MB are fine to read all at once. Files above 100MB should be streamed. Between 50–100MB, benchmark both approaches on your specific hardware and data shape. Also consider whether prettifying a multi-hundred-MB JSON file is really the right tool — that might be a sign to switch to a line-delimited JSON (NDJSON) format instead.

    FAQ: Prettifying JSON in Node.js

    Does JSON.stringify preserve key order?

    Yes — mostly. JSON.stringify follows the ECMAScript specification for property enumeration order. Integer-like keys are sorted numerically first, then string keys appear in insertion order. For the vast majority of objects (no integer keys), the output will match the insertion order exactly. If you need a guaranteed alphabetical sort, use a replacer function or sort the keys before stringifying:

    // Sort all keys alphabetically before prettifying
    function prettifySorted(obj, indent = 2) {
      return JSON.stringify(obj, Object.keys(obj).sort(), indent);
    }
    
    // Deep sort (recursive for nested objects)
    function sortKeysDeep(obj) {
      if (Array.isArray(obj)) return obj.map(sortKeysDeep);
      if (obj !== null && typeof obj === "object") {
        return Object.fromEntries(
          Object.keys(obj).sort().map((k) => [k, sortKeysDeep(obj[k])])
        );
      }
      return obj;
    }
    console.log(JSON.stringify(sortKeysDeep({ z: 3, a: 1, m: 2 }), null, 2));

    What indent size should I use — 2 or 4 spaces?

    This is largely a matter of team convention. The JavaScript/Node.js ecosystem strongly favors 2 spaces — it's the default for npm's package.json, Prettier's default, and widely used in popular open-source projects. Python and many other language ecosystems favor 4 spaces. If you have a .prettierrc or .editorconfig file in your project, let it define the standard. When in doubt, use 2 spaces for JSON files that will be committed to source control — smaller diffs and better readability on GitHub.

    Can I prettify JSON that contains comments (JSON5 or JSONC)?

    Standard JSON.parse does not support comments — they are not part of the JSON specification. If your file uses JSON5 (used by some config files like tsconfig.json) or JSONC (JSON with Comments, used by VS Code settings), you need a specialized parser:

    • json5 npm package — parses JSON5 format and can stringify it back.
    • strip-json-comments npm package — strips comments before passing to JSON.parse.
    • VS Code's built-in JSONC parser (jsonc-parser npm package) — handles JSONC precisely.

    How do I prettify JSON in the browser (not Node.js)?

    The exact same JSON.stringify(data, null, 2) API works in all modern browsers — it's part of the JavaScript standard, not Node.js-specific. In a browser context you might display the prettified result inside a <pre> tag for monospaced formatting, or inject it into a <textarea>. For a richer experience with syntax highlighting and tree navigation, use an online JSON viewer tool that handles all of that automatically — no code required.

    Conclusion

    Prettifying JSON in Node.js is a foundational skill with a wide range of practical applications — from debugging API integrations to maintaining clean configuration files to building developer tools. To recap the five methods covered in this guide:

    1. JSON.stringify(data, null, 2) — The built-in, zero-dependency solution. Ideal for quick formatting in scripts and APIs.
    2. fs module — Read, prettify, and write JSON files on disk. Perfect for automation scripts and build tools.
    3. Express.js app.set('json spaces', 2) — Pretty-print all API responses automatically in your Express server.
    4. Prettier library — Enforce consistent, opinionated JSON formatting across your entire project, including in CI/CD.
    5. CLI with node -e or jq — Instant terminal one-liners for quick on-the-fly formatting without writing a script.

    Remember to handle edge cases like circular references, undefined values, and BigInt serialization to avoid surprising runtime errors. And for large files, reach for streaming solutions like stream-json to keep memory usage in check.

    Whether you prefer a programmatic approach in your Node.js code or a quick visual inspection without any setup, the right tool depends on your workflow. For the fastest, no-install experience — especially when you just want to paste and read a JSON blob — an online viewer is unbeatable.

    Try Our Free Online JSON Viewer & Prettifier

    Need to prettify a JSON blob right now — no Node.js required? Our JSON Viewer instantly formats, validates, and visualizes your JSON with syntax highlighting, a collapsible tree view, and error detection. Just paste your JSON and get beautiful, readable output in seconds.

    Open JSON Viewer →