{ }jsonkitOpen

How to minify JSON (and when you should)

7 min read · updated 2026-09-24

To minify JSON, you remove every byte a parser does not need: the spaces, tabs and newlines that help people read it but carry no meaning. You get the same data in fewer bytes, such as {"id":1,"name":"Ada"} instead of the same object over five indented lines.

This guide covers what minification removes, what it saves, and how to do it in JavaScript, Python and on the command line. It also explains how minification interacts with gzip and Brotli, and when to keep your JSON pretty-printed. For the opposite task, see How to format and beautify JSON.

What JSON minification does

JSON has two kinds of whitespace. Insignificant whitespace sits between tokens, such as the indentation before a key, the space after a colon or the newline at the end of a line. Significant whitespace sits inside string values, where a space or \n is real data. Minification removes all of the first kind and none of the second.

A minifier tokenizes the document and writes it back with the tokens packed together. There is no indentation, no line breaks, and exactly one comma or colon between neighbors. Numbers, booleans, null, key order and string contents stay byte-for-byte the same.

The same object, pretty-printed and then minified. Same data, fewer bytes.json
// Pretty (48 bytes)
{
  "id": 1,
  "name": "Ada",
  "active": true
}

// Minified (35 bytes)
{"id":1,"name":"Ada","active":true}

Some things did not change. The string "Ada" still has its quotes, and true is still a boolean. A value with a space in it, like "New York", keeps that space. A correct minifier only removes whitespace between structural tokens.

Why minify: payload size and performance

Minifying saves bytes. Pretty-printed JSON can be 15-50% larger than its minified form, depending on nesting depth and indent width. Each level of nesting adds leading spaces to every line inside it. For a document served millions of times a day, that overhead costs bandwidth, adds latency and fills cache entries.

Where the savings show up

  • Network transfer. Fewer bytes on the wire means a faster time to last byte. This matters most on mobile and high-latency connections.
  • Memory and cache. Minified payloads take less room in CDN edge caches, Redis and browser storage, so more entries fit in the same budget.
  • Bundle size. JSON embedded in a JavaScript bundle, such as translation catalogs, config or seed data, ships to every visitor. Smaller JSON means a smaller critical-path download.

Minification does not make parsing much faster. A JSON parser skips whitespace in one cheap pass, so a minified document parses at about the same speed as a formatted one. The gain is in transfer and storage, not CPU. Keep that in mind if someone says minifying will fix a slow endpoint.

JSON MinifierPaste any JSON and get minified, single-line output. Runs in your browser. Nothing is uploaded.→

How to minify JSON in code

You rarely need a library for this. Mainstream JSON serializers emit minified output by default. Pretty-printing is the option you turn on.

JavaScript / Node.js

JSON.stringify with one argument produces minified JSON. The optional second and third arguments (a replacer and an indent width) add whitespace. Leave them out and you get the compact form.

Minify by round-tripping through parse then stringify.js
const pretty = `{
  "id": 1,
  "tags": ["a", "b"]
}`;

// Parse, then stringify with no indent argument:
const minified = JSON.stringify(JSON.parse(pretty));

console.log(minified);
// {"id":1,"tags":["a","b"]}

// Compare: the third argument is what pretty-prints
JSON.stringify({ id: 1 }, null, 2);
// {\n  "id": 1\n}

Python

Python's json.dumps adds no newlines by default, but it leaves a space after every , and :. Pass the separators argument to remove them and match JSON.stringify output. See Working with JSON in Python for more.

Use compact separators for true minification in Python.python
import json

data = {"id": 1, "tags": ["a", "b"]}

# Default still has spaces after ',' and ':'
json.dumps(data)                 # '{"id": 1, "tags": ["a", "b"]}'

# Compact separators remove them
json.dumps(data, separators=(",", ":"))
# '{"id":1,"tags":["a","b"]}'

Minify JSON with jq -c

jq is the standard command-line JSON processor, and jq -c . is the shortest way to minify JSON in a shell. The . is jq's identity filter, which outputs its input unchanged. -c (--compact-output) prints each result on one line with no whitespace between tokens. jq parses the input first, so invalid JSON fails with a parse error and a non-zero exit code. The minify step also validates.

The basic jq -c commands.bash
# Minify a file to stdout
jq -c . data.json

# Save the minified copy next to the original
jq -c . data.json > data.min.json

# Minify a stream of API responses
curl -s https://api.example.com/items | jq -c .

Minifying files in place

jq has no in-place flag. If you redirect output to the file you are reading (jq -c . a.json > a.json), the shell truncates it before jq reads it, and you get an empty file. Write to a temporary file and move it over the original only if jq succeeded. Or use sponge from moreutils, which waits for all input before writing.

jq cannot edit in place, so write through a temp file.bash
# One file, safely
jq -c . data.json > data.json.tmp && mv data.json.tmp data.json

# With sponge (moreutils)
jq -c . data.json | sponge data.json

# Every .json file in a directory
for f in *.json; do
  jq -c . "$f" > "$f.tmp" && mv "$f.tmp" "$f"
done

Arrays to one object per line

jq -c '.[]' writes each element of a top-level array on its own line, minified. That is the NDJSON / JSON Lines format that log pipelines and bulk-import APIs expect. To go the other way, jq -c -s . (slurp) reads a stream of values and wraps them in one minified array.

Converting between a JSON array and NDJSON with jq.bash
# [{"id":1},{"id":2}]  ->  one object per line
jq -c '.[]' items.json > items.ndjson

# NDJSON  ->  one minified array
jq -c -s . items.ndjson > items.json

Key order, Unicode and numbers

  • Key order is preserved. jq keeps object keys in input order. Add -S (--sort-keys) to sort them, which helps with stable diffs and hashing. See How to sort JSON keys.
  • Unicode stays literal. Non-ASCII characters are written as UTF-8. Add -a (--ascii-output) to emit \uXXXX escapes instead.
  • Multiple documents stay separate. If the input has several top-level values, jq -c . prints each one minified on its own line. It does not merge them.
  • Number precision depends on the jq version. jq 1.6 and earlier convert every number to a 64-bit float, so integers above 2^53 (such as 64-bit IDs) can be rounded without warning. jq 1.7 and later keep the precision of numbers that pass through unchanged, but may normalize the notation (1E2 becomes 1E+2). Run jq --version before you minify data with large IDs.

How minification interacts with gzip and Brotli

Most "always minify" advice skips this. HTTP responses are almost always compressed with gzip or Brotli, and compression is very good at shrinking repeated indentation and newlines. After compression, the gap between pretty and minified JSON is much smaller than the raw byte difference, often only a few percent.

If your server already gzips responses, minifying still gives a smaller but real gain and a lighter cache footprint. If you ship JSON *uncompressed*, for example embedded in a bundle, stored in a database column or sent over a raw socket, minification matters much more. Nothing else removes that whitespace.

When to minify JSON and when not to

Minify JSON at the point where it leaves your system. Keep it readable anywhere a person might look at it. In short, machines get minified JSON and people get formatted JSON.

SituationMinify?Why
Production API responsesYesSmaller payloads, less cache pressure at scale
JSON embedded in a JS bundleYesShips to every visitor on the critical path
Config stored in a DB column or KVYesUncompressed storage benefits directly
Files committed to gitNoMinified diffs are unreadable, so you lose line-by-line review
Config files humans editNoReadability and merge-friendliness matter more than bytes
Log lines and debug outputNoYou need to read these under pressure
Local development responsesOptionalPretty-print to inspect, or minify to match production

Source control is the main case to avoid. A minified file is one huge line, so git diff marks the whole file as changed even when one value moved, and review stops being practical. Commit formatted JSON and minify it in a build or deploy step. To compare two versions of a document, the JSON Diff tool compares structure, ignores formatting and shows only real changes.

Minification is lossless and safe to reverse

Minification removes no information. It only deletes whitespace between tokens, so you can run the output through a JSON Formatter and get a readable document back. It may not match the *original* byte for byte, since the indent style can differ. The values, types and structure are the same. Parse either version and you get identical objects.

Whitespace inside strings is safe with a correct minifier, because it sits inside quotes and is left alone. Be careful with tools that "minify" some other way. A correct minifier parses and re-serializes. A naive regex that deletes whitespace will corrupt any string with spaces or newlines. If you are unsure, run the result through a JSON Validator to check that it is still well-formed.

Frequently asked questions

Does minifying JSON make it parse faster?

Not by much. Parsers skip whitespace in one cheap pass, so a minified document parses at about the same speed as a formatted one with the same data. The real gain is smaller payloads: less bandwidth, less memory and smaller caches.

Is minifying JSON lossless?

Yes. Minification only removes whitespace between tokens. String contents, numbers, booleans, null and key order stay the same. You can pretty-print the minified output at any time and get the same data, structure and types back.

How do I minify JSON in JavaScript?

Call JSON.stringify with one argument, JSON.stringify(obj). The output is minified by default. The optional third argument (indent width) is what adds whitespace. To minify a pretty-printed string, use JSON.stringify(JSON.parse(str)).

Should I minify JSON if my server already uses gzip?

Yes, but the gain is smaller than the raw byte difference suggests. Gzip and Brotli compress repeated whitespace to almost nothing. Minifying still reduces memory and cache use and trims a few percent off the compressed size. Production setups usually do both.

How do I minify a JSON file from the command line?

Run jq -c . data.json to print the minified version to stdout. jq can't edit in place, so write to a temp file and move it with jq -c . data.json > out.json && mv out.json data.json.

Does jq -c change key order or numbers?

It keeps keys in their original order unless you add -S to sort them. Numbers depend on the version. jq 1.6 and earlier store every number as a 64-bit float, so very large integers can lose precision. jq 1.7 and later keep numbers that pass through unchanged.

Should I commit minified JSON to git?

No. Minified JSON is one long line, so diffs show the whole file as changed and code review becomes impractical. Commit formatted JSON and minify it in a build or deploy step.