How to Pretty-Print JSON in Go: A Complete Guide with Examples

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Why does JSON in Go look like a mess and how to fix it?

\n

Have you ever written a Go program that outputs JSON and gotten something like this in your terminal?

\n
{"name":"PythonLib","year":2025,"tags":["go","json","tutorial"],"active":true}
\n

Agreed, reading this without special tools is not exactly a pleasure. Especially when the data structure is complex and the nesting goes several levels deep. Your eyes start to wander, and finding the right field becomes a real quest.

\n

The good news: Go has built-in tools that turn this "mess" into a neat, structured document. And today we'll cover all the ways to beautifully format JSON — from simple use of the standard library to creating your own pretty-print tool.

\n

This material is based on a real question from Stack Overflow (over 50,000 views), so the topic is truly in demand. Let's go!

\n\n

What is pretty-print and why is it needed?

\n

Pretty-print (or "beautiful printing") is formatting data with indentation, line breaks, and alignment to make it human-readable. In the context of JSON, this means:

\n
    \n
  • Adding spaces or tabs for nested elements
  • \n
  • Putting each key-value pair on a new line
  • \n
  • Aligning values for clarity
  • \n
\n

Why is this needed in Go? Imagine you are debugging an API response, writing a logger, or simply outputting a configuration. Unformatted JSON takes up less space but is completely unreadable. Pretty-print solves this problem in a couple of lines of code.

\n\n

Method 1: json.MarshalIndent — the standard solution

\n

The simplest and recommended way is to use the json.MarshalIndent function from the standard encoding/json package. It does exactly what you need: takes data and returns formatted JSON with indentation.

\n

Here is a basic example:

\n
package main\n\nimport (\n    "encoding/json"\n    "fmt"\n    "log"\n)\n\ntype Site struct {\n    Name   string   `json:"name"`\n    Year   int      `json:"year"`\n    Tags   []string `json:"tags"`\n    Active bool     `json:"active"`\n}\n\nfunc main() {\n    site := Site{\n        Name:   "PythonLib",\n        Year:   2025,\n        Tags:   []string{"go", "json", "tutorial"},\n        Active: true,\n    }\n\n    // Prefix — "", indent — "  " (two spaces)\n    prettyJSON, err := json.MarshalIndent(site, "", "  ")\n    if err != nil {\n        log.Fatalf("Marshaling error: %v", err)\n    }\n\n    fmt.Println(string(prettyJSON))\n}
\n

Result:

\n
{\n  "name": "PythonLib",\n  "year": 2025,\n  "tags": [\n    "go",\n    "json",\n    "tutorial"\n  ],\n  "active": true\n}
\n

Beautiful, right? Notice the second and third parameters of MarshalIndent:

\n
    \n
  • Prefix — a string added to the beginning of each line. Usually an empty string "".
  • \n
  • Indent — a string for each nesting level. Most often two spaces " " or a tab "\\t" are used.
  • \n
\n\n

Configuring indentation: spaces vs tabs

\n

You can easily change the indentation style. For example, with a tab:

\n
prettyJSON, _ := json.MarshalIndent(site, "", "\\t")\nfmt.Println(string(prettyJSON))
\n

Result:

\n
{\n\t"name": "PythonLib",\n\t"year": 2025,\n\t"tags": [\n\t\t"go",\n\t\t"json",\n\t\t"tutorial"\n\t],\n\t"active": true\n}
\n

Which option to choose? If your project follows Go standards (and they recommend tabs for code), use "\\t". If you work in a team where spaces are the norm, two spaces will be more appropriate. The main thing is consistency.

\n\n

Method 2: Pretty-print for raw JSON strings

\n

What if you already have a string with unformatted

Blogs

Book Recommendations