Skip to main content
~/makemydev/blog/validate-json-command-line-browser

How to validate JSON at the command line and in the browser

JSON Formatter#008·7 min read·

You have a JSON file. Something is wrong with it. Maybe an API returned a blob that your parser chokes on. Maybe you hand-edited a config file and introduced a trailing comma. You need to find out where the problem is, fast.

Here are the tools I actually reach for, ordered from quickest shell one-liner to full-featured browser option.

jq: the Swiss Army knife

If you work with JSON regularly and don’t have jq installed, stop reading and go install it. On macOS: brew install jq. On Ubuntu: apt install jq.

To validate a file:

jq . config.json

If the JSON is valid, jq pretty-prints it. If not, you get an error with a line and column number:

parse error (Invalid numeric literal at line 12, column 5)

For piped input (say, from curl), the same thing works:

curl -s https://api.example.com/data | jq .

If you only care about validity and don’t want the output, use jq empty:

jq empty response.json && echo "Valid" || echo "Invalid"

The exit code is 0 for valid JSON and non-zero for invalid. This makes jq useful in shell scripts and CI pipelines where you want to gate a deployment on config validity.

Python: already on your machine

Every macOS and most Linux systems ship with Python. The json.tool module validates and pretty-prints in one command:

python3 -m json.tool config.json

On invalid input, you get a traceback ending with something like:

json.decoder.JSONDecodeError: Expecting ',' delimiter: line 8 column 3 (char 142)

The error message is more verbose than jq’s, but it gives you the line, column, and character offset. The character offset is occasionally useful when the line/column doesn’t match what your editor shows (usually a tab-width disagreement).

Python’s JSON parser is stricter than jq in some edge cases. It rejects duplicate keys by default (as of Python 3.1), while jq silently keeps the last value. If you’re debugging a “works in one tool but not another” situation, try both.

Node.js one-liners

If you’re in a JavaScript project, Node is already in your PATH. The simplest validation:

node -e "JSON.parse(require('fs').readFileSync('config.json', 'utf8'))"

On failure, you get:

SyntaxError: Expected ',' or '}' after property value in JSON at position 142

Node’s JSON.parse gives you a character position but not a line number. To get line and column, wrap it:

node -e "
const src = require('fs').readFileSync('config.json', 'utf8');
try { JSON.parse(src); console.log('Valid'); }
catch (e) {
  const pos = parseInt(e.message.match(/position (\d+)/)?.[1] ?? '-1');
  if (pos >= 0) {
    const lines = src.slice(0, pos).split('\n');
    console.error('Line ' + lines.length + ', col ' + lines.at(-1).length);
  }
  console.error(e.message);
  process.exit(1);
}
"

This is clunky compared to jq, but it uses the same parser your application uses — which matters when you’re debugging a parsing failure in a Node app.

Browser DevTools

Open any browser, press F12, go to the Console tab, and type:

JSON.parse(`paste your json here`)

Use backticks so you can paste multi-line content without escaping newlines. If the JSON is valid, the console displays the parsed object with expandable nodes. If it’s invalid, you get a SyntaxError with a position.

Chrome’s DevTools also has a trick: if you navigate directly to a JSON file (drag it onto a browser tab, or open a file:/// URL), Chrome will attempt to parse and display it. If the JSON is malformed, you’ll see the raw text and can then paste it into the console for a proper error.

Firefox has a built-in JSON viewer that activates when you open a .json file or navigate to a URL with a application/json content type. It shows a pretty-printed tree, a raw view, and headers. When the JSON is broken, it tells you at the top of the page.

Common JSON mistakes

Before you reach for any tool, here are the errors that account for the vast majority of hand-editing breakage:

  • Trailing commas. JSON does not allow a comma after the last element in an array or object. {"a": 1, "b": 2,} is invalid. JavaScript allows this; JSON does not.
  • Single quotes. JSON requires double quotes for strings. {'key': 'value'} will fail.
  • Unquoted keys. {key: "value"} is JavaScript, not JSON. Every key must be a double-quoted string.
  • Comments. JSON has no comment syntax. No //, no /* */. If you need comments in config files, consider JSONC (used by VS Code’s settings.json and tsconfig.json) or switch to YAML.
  • Unescaped control characters. Literal tabs and newlines inside strings are invalid. Use \t and \n.

Validating in CI/CD

If you have JSON config files checked into your repo (feature flags, i18n strings, API schemas), validate them in CI so broken commits don’t merge. A simple approach with jq:

# In a GitHub Actions step or similar
find . -name "*.json" -not -path "./node_modules/*" | while read f; do
  jq empty "$f" || { echo "Invalid JSON: $f"; exit 1; }
done

Or with Python, if jq isn’t available in your CI image:

python3 -c "
import json, glob, sys
errors = []
for f in glob.glob('**/*.json', recursive=True):
    if 'node_modules' in f: continue
    try: json.load(open(f))
    except json.JSONDecodeError as e: errors.append(f'{f}: {e}')
if errors:
    print('\n'.join(errors))
    sys.exit(1)
print(f'All JSON files valid')
"

Both approaches give you early feedback. The Python version also works on Windows CI runners where jq might not be pre-installed.

Browser-based validation with MakeMyDev

Sometimes you’re not at a terminal. Maybe you’re reviewing a Slack message, reading documentation, or working from a tablet. The JSON Formatter on this site lets you paste JSON and immediately see whether it’s valid, with error messages that include line and column numbers.

It also formats and minifies, which is useful when you’re staring at a single-line blob from an API response and need to figure out what you’re looking at. The output is syntax-highlighted, so structure is visible at a glance.

Everything runs in your browser. The JSON never leaves your machine, which matters when you’re working with credentials, tokens, or other sensitive payloads that you shouldn’t paste into random websites.

Which tool when?

A quick decision tree:

  • Quick check on a file: jq empty file.json
  • No jq installed, have Python: python3 -m json.tool file.json
  • Debugging a Node app: use the node -e approach so you’re testing with the same parser
  • JSON from clipboard, no terminal handy: browser console or the JSON Formatter
  • CI pipeline: jq in a shell script, or the Python glob approach

None of these tools are better in absolute terms. They have different availability and different strengths. jq is the fastest if it’s installed. Python is the most portable. Node matches your app’s parser. The browser works when everything else is unavailable. Pick the one that fits the situation.