EthicalFusion
Data & Developers

How to Format JSON: Pretty-Print, Validate and Read Errors

Paste JSON into a formatter to indent it and catch errors. The exact syntax rules, how to read an error position, and how to do it in VS Code, Python and jq.

By the EthicalFusion team Published Updated 10 min read

To format JSON, run it through a parser that reads it and prints it back with indentation. The free JSON formatter does this in your browser with two spaces per level, and if the JSON is broken it shows the parser's error with a line and column instead. In VS Code, press Shift+Alt+F (Shift+Option+F on a Mac). On the command line, run python -m json.tool data.json or jq . data.json.

Formatting and validating are really one job: a formatter can only re-indent JSON it managed to read. This guide covers the syntax rules that decide whether JSON is valid, how to choose an indentation, how to read an error position, and what each method does differently. For a list of the usual mistakes and their fixes, see the most common JSON errors.

Format JSON in your browser

Paste the text into the JSON formatter and press Format JSON. The tool hands your text to the browser's own JSON parser, then prints the result with two-space indentation. Nothing is uploaded, so it is fine for API responses that contain tokens or customer details. Three related tools use the same parser:

  • The JSON validator only checks. It says "✓ Valid JSON" or shows the error message.
  • The JSON minifier removes every space and line break between values.
  • The JSON string escaper turns plain text containing quotes and line breaks into a valid JSON string you can paste into a file.

Because the formatter rebuilds the data rather than just adding spaces, three things can change. Know them before you format anything important:

  • Very large integers lose precision. JavaScript stores every number as a 64-bit float, so integers above 9,007,199,254,740,991 are rounded. In our test, 12345678901234567890 came out as 12345678901234567000. Long numeric IDs from some payment and social media APIs are affected. Python's json.tool and jq kept the original digits.
  • Duplicate keys disappear. {"a":1,"a":2} becomes {"a": 2}. The last value wins, with no warning.
  • Number-like keys move to the front. In {"b":1,"2":"two","1":"one"}, JavaScript puts "1" and "2" first, in numeric order. The data means the same thing, but a line-by-line diff against the original will show changes.

The JSON syntax rules (RFC 8259 and ECMA-404)

JSON is defined by two matching standards: RFC 8259 from the IETF (December 2017) and ECMA-404 from Ecma International. The grammar is small and strict. Most "invalid JSON" comes from writing JavaScript object syntax, which is far more forgiving. These are the rules that catch people:

RuleValidInvalid
Strings and keys use double quotes"name": "Asha"'name': 'Asha'
Every key is quoted{"city": "Pune"}{city: "Pune"}
Commas only go between items[1, 2, 3][1, 2, 3,]
No comments of any kind(none)// note or /* note */
Literal names are lowercasetrue, false, nullTrue, NULL, undefined
Plain decimal numbers only7, -0.5, 1e3007, +5, NaN, 0x1F
Control characters in strings are escaped"line one\nline two"A real line break or tab inside the quotes

A few more points from RFC 8259. The top level can be any value, so a bare "hello" or 42 is valid JSON text, although APIs nearly always send an object or an array. Whitespace between tokens may only be spaces, tabs, line feeds and carriage returns. JSON exchanged between systems must be encoded as UTF-8. And keys inside one object "SHOULD be unique", which is a recommendation rather than a rule; that is why parsers handle duplicates differently instead of rejecting them.

Choosing an indentation

Indentation is cosmetic. Every parser reads all of these styles the same way, and an object's keys have no meaningful order, so choose one style per project and keep it; then diffs show only real changes. Here is the same small order record (a nested customer and two items) in each style. Minified, it reads:

{"order_id":"EF-1042","customer":{"name":"Asha Rao","city":"Pune"},"items":[{"sku":"TEA-250","qty":2,"price":180},{"sku":"MUG-01","qty":1,"price":349}],"paid":true,"coupon":null}

StyleDefault inSize of this record
MinifiedAPIs; the site's minifier178 bytes
2 spacesThe site's formatter; jq; most JavaScript projects285 bytes
4 spacesPython's json.tool359 bytes
TabsAvailable as --tab in Python and jq248 bytes

Two-space indentation made this record 60% larger and four spaces doubled it. If your server compresses responses with gzip or Brotli, most of that gap disappears in transit, but minifying still helps for JSON stored in a database, embedded in a page or sent without compression. Sorting keys alphabetically (--sort-keys in Python, -S in jq) is useful just before you compare two files.

How to read a JSON error position

Every parser reports where it gave up, not where you made the mistake. The two are often different, because a parser only knows something is wrong when it meets a character that cannot come next. Take this four-line object with a trailing comma on line 3:

LineText
1{
2"name": "Asha", (indented two spaces)
3"city": "Pune", (indented two spaces)
4}

We ran it through three parsers. These are the exact messages:

ParserMessage
Chrome and Edge (also what the site's formatter shows there)Expected double-quoted property name in JSON at position 38 (line 4 column 1)
Python 3.14, json.toolIllegal trailing comma before end of object: line 3 column 17 (char 36)
jq 1.8.1Expected another key-value pair at line 4, column 1

Chrome and jq point at the closing brace on line 4, because after a comma they expected another key. Recent Python names the comma itself. "Position" and "char" count characters from zero, starting at the very first character and including line breaks, while "line" and "column" count from 1. So position 38 is the 39th character, which here is the }.

A missing comma is the classic error that shows up a line late. With line 2 written as "name": "Asha" (no comma), Chrome reports "Expected ',' or '}' after property value in JSON at position 21 (line 3 column 3)" and Python says "Expecting ',' delimiter: line 3 column 3". Line 3 is fine; the comma belongs at the end of line 2. When the reported line looks correct, check the end of the line above it.

Two more messages are worth recognising. "Bad control character in string literal" means a string contains a raw tab or line break; replace it with \t or \n. "Unexpected token '<', "<!DOCTYPE "... is not valid JSON" means you received an HTML page, usually an error or login page, instead of JSON, so the fix is in the request rather than the text. Other browsers word these messages differently, so copy the message exactly when you search for it.

Format JSON in VS Code

  1. Open the file and check the language mode at the bottom right of the status bar. If it says Plain Text, click it and choose JSON.
  2. Press Shift+Alt+F on Windows, Shift+Option+F on macOS or Ctrl+Shift+I on Linux. You can also right-click and choose Format Document.
  3. If nothing changes, the file has a syntax error. VS Code underlines it in red and lists it in the Problems panel (Ctrl+Shift+M).

VS Code indents with the file's indentation setting, shown in the status bar as "Spaces: 2" or "Spaces: 4"; click it to change. To format every time you save, turn on editor.formatOnSave in Settings.

One trap: VS Code's own settings files (settings.json, tasks.json, launch.json) use a mode called JSON with Comments. It allows // and /* */ comments and accepts trailing commas with a warning. That is not standard JSON, so if you copy a snippet from those files into an API request or a package.json, remove the comments first.

Format JSON on the command line

Python includes a JSON formatter, so this works on any machine with Python 3.9 or later. jq is a separate download from jqlang.org but is the standard tool for JSON in shell scripts. We tested every command below with Python 3.14 and jq 1.8.1:

TaskPythonjq
Pretty-printpython -m json.tool data.json (4 spaces)jq . data.json (2 spaces)
Set the indent--indent 2--indent 4
Indent with tabs--tab--tab
Minify--compact-c
Sort keys--sort-keys-S
Validate onlyExits with status 1 and prints the errorjq empty data.json exits with status 5 on an error
Save to a filepython -m json.tool in.json out.jsonjq . in.json > out.json

Python escapes every non-ASCII character by default, so "₹20" becomes "₹20" and Hindi text turns into strings of \u codes. Add --no-ensure-ascii to keep the characters. On Windows, printing them to the console can then fail with a "charmap" codec error; use python -X utf8 -m json.tool --no-ensure-ascii data.json or write to an output file instead. jq prints UTF-8 text as it is. From Python 3.14 you can also type python -m json; the older json.tool form still works.

Both tools kept long integers exact in our test, so if your data carries big numeric IDs, the command line is the safer place to format it.

Minify, convert or reuse it

Keep JSON formatted while you read, edit and commit it, and minify it when a machine is the only reader: request bodies, values stored in a database column, or config embedded in a page. The minifier gives exactly what JSON.stringify gives, so the same large-number caveat applies.

Once the JSON is valid, the JSON to CSV converter turns an array of objects into a spreadsheet; it collects every key it finds as a column and writes nested objects as JSON text inside the cell. The JSON to TypeScript tool builds interfaces from the first item of an array, and treats null values as any, so check those by hand. For the reverse trip, see how to convert CSV to JSON.

Frequently asked questions

Can JSON have comments?

No. The grammar in RFC 8259 has no comment syntax, so any // or /* */ makes the text invalid. If you need a note inside the data, add an ordinary key such as "_comment". Formats like JSON with Comments (used by VS Code settings) and JSON5 allow comments, but only tools built for them can read those files.

What is the difference between a JSON formatter and a JSON validator?

Both parse the text the same way. A validator stops after parsing and tells you whether it worked; a formatter goes on to print the data with indentation. If the JSON is invalid, both show the same error.

How do I format JSON with 4 spaces?

The site's formatter always uses two spaces. For four, use python -m json.tool (its default), jq --indent 4 ., or set "Spaces: 4" in VS Code's status bar before pressing Shift+Alt+F.

Why does my formatted JSON show ₹ instead of ₹?

Python's json.tool escapes non-ASCII characters by default. Both forms mean the same character, but add --no-ensure-ascii if you want the readable version. The browser formatter and jq keep the original characters.

Is it safe to paste API responses into an online JSON formatter?

It depends on the tool. The formatter, validator and minifier on this site run entirely in your browser and send nothing to a server. Other sites may upload what you paste, so check before pasting tokens, passwords or customer data, and treat a leaked key as compromised.

Are single quotes allowed in JSON?

No. Strings and keys must use double quotes. Single quotes are valid in JavaScript and Python code, which is why copying an object literal from code is the most common source of invalid JSON.

Sources: IETF RFC 8259, The JavaScript Object Notation (JSON) Data Interchange Format (December 2017); ECMA-404; Visual Studio Code documentation, JSON; Python 3 documentation, json module command-line interface; jq 1.8 manual. Error messages tested with Node.js 24 (V8), Python 3.14 and jq 1.8.1.

  • #json formatter
  • #json validator
  • #pretty print json
  • #json syntax
  • #jq
  • #python json.tool

Tools used in this guide

Free, no sign-up, and they run in your browser.

About EthicalFusion

EthicalFusion offers 321 free online tools for money, documents, images, writing and code. This guide was written by the team that builds them. Calculators give estimates, so confirm important figures with your bank, CA or doctor.

About us Suggest a correction

Keep reading

All articles