JSON Formatting Best Practices
JSON (JavaScript Object Notation) has become the de facto standard for data exchange on the web. APIs return JSON, configuration files use JSON, and even databases store JSON documents. Despite its simplicity, JSON has strict syntax rules that are easy to violate, and poorly formatted JSON causes debugging headaches, performance problems, and security vulnerabilities. This guide covers everything you need to know about formatting JSON correctly, from basic syntax to advanced topics like schema validation and handling large files.
What Is JSON?
JSON is a lightweight, text-based data interchange format derived from JavaScript object literal syntax. It was specified by Douglas Crockford in the early 2000s and standardized as ECMA-404 and RFC 8259. JSON's design goals were simplicity, human readability, and ease of implementation across programming languages. Today, every major programming language includes built-in JSON support.
JSON supports six data types: strings (in double quotes), numbers
(integers and floats), booleans (true and
false), the null value (null), objects
(unordered key-value collections), and arrays (ordered lists). It does
not support comments, dates, binary data, or undefined values
natively.
JSON Syntax Rules
JSON has a strict syntax that must be followed exactly. Even a single character error will cause the entire document to fail parsing. Understanding these rules prevents the most common formatting errors.
Strings Must Use Double Quotes
All string values and object keys must be enclosed in double quotes. Single quotes are not valid JSON string delimiters. This is one of the most common mistakes for developers coming from JavaScript, where single and double quotes are interchangeable.
// Invalid - single quotes
{'name': 'Alice', 'age': 30}
// Valid - double quotes
{"name": "Alice", "age": 30}
Object Keys Must Be Quoted
Unlike JavaScript object literals, JSON requires all object keys to be enclosed in double quotes. Unquoted keys are a syntax error.
// Invalid - unquoted keys
{name: "Alice", age: 30}
// Valid - quoted keys
{"name": "Alice", "age": 30}
No Trailing Commas
JSON does not allow a comma after the last item in an object or array. This is another common mistake for JavaScript developers, where trailing commas are permitted (and even encouraged in some style guides).
// Invalid - trailing comma
{
"name": "Alice",
"age": 30,
}
// Valid - no trailing comma
{
"name": "Alice",
"age": 30
}
No Comments
JSON does not support comments. Neither // single-line
comments nor /* */ multi-line comments are valid in JSON.
If you need to include documentation, consider using a separate
documentation file or a format like JSONC (JSON with Comments) that
some tools support.
Strict Value Types
JSON values must be one of the six supported types.
undefined, NaN, Infinity, and
-Infinity are not valid JSON values. Including any of
these will cause a parse error or produce non-standard JSON that many
parsers will reject.
Common Formatting Mistakes
Beyond syntax errors, there are several formatting mistakes that produce technically valid but problematic JSON:
- Inconsistent indentation: Mixing tabs and spaces, or using different indentation depths, makes JSON harder to read in code reviews and diffs. Standardize on 2-space indentation, which is the most common convention.
- Deeply nested structures: JSON nested more than 4-5 levels deep becomes difficult to read and debug. Consider flattening the structure or splitting it into separate documents.
- Inconsistent key ordering: While JSON objects are technically unordered, maintaining a consistent key order (such as alphabetical or by importance) makes diffs more meaningful and reduces merge conflicts in version control.
- Excessively long lines: Arrays with many items on a single line are hard to scan. Break long arrays into multiple lines with one item per line for readability.
- Missing or inconsistent null handling: Decide whether to omit null values entirely or include them explicitly, and apply that decision consistently across your API.
Pretty Printing vs Minification
The two primary formatting modes for JSON serve different purposes, and using the right one in the right context is important.
Pretty-Printed JSON
Pretty printing adds indentation and line breaks to make JSON readable by humans. This is essential during development, debugging, and documentation. Most JSON formatters use 2-space indentation by default:
{
"users": [
{
"id": 1,
"name": "Alice",
"email": "alice@example.com"
},
{
"id": 2,
"name": "Bob",
"email": "bob@example.com"
}
]
}
Minified JSON
Minification removes all unnecessary whitespace, producing the smallest possible valid JSON. This is critical for production APIs where every byte counts:
{"users":[{"id":1,"name":"Alice","email":"alice@example.com"},{"id":2,"name":"Bob","email":"bob@example.com"}]}
When to Use Each
| Context | Format | Reason |
|---|---|---|
| Development and debugging | Pretty-printed | Readability and quick scanning |
| Configuration files | Pretty-printed | Humans need to read and edit these |
| Production API responses | Minified | Smaller payload, faster transfer |
| Log files | Minified (one object per line) | Compact storage, grep-friendly |
| Version control | Pretty-printed | Meaningful diffs and fewer merge conflicts |
JSON Schema Validation
While JSON syntax validation checks that a document is well-formed, it does not verify that the data has the expected structure, types, or values. JSON Schema fills this gap by providing a vocabulary for describing the expected shape of JSON data.
What Is JSON Schema?
JSON Schema is a JSON document that describes the structure of other JSON documents. It lets you specify required fields, expected types, value ranges, string patterns, and nested object structures. A JSON document that conforms to a schema is called a valid instance.
Common Schema Features
- Type checking: Ensure fields are strings, numbers, booleans, objects, or arrays.
- Required fields: Specify which properties must be present.
- String validation: Enforce patterns (regex), minimum/maximum length, and formats (email, date-time, URI).
- Number validation: Set minimum, maximum, exclusive bounds, and multiple-of constraints.
- Array validation: Control item types, minimum/maximum item count, and uniqueness.
-
Composition: Use
allOf,anyOf,oneOf, andnotfor complex validation logic.
When to Use Schema Validation
Use JSON Schema validation whenever you receive JSON from external sources: API request bodies, configuration files, data imports, and message queue payloads. Schema validation catches errors early, provides clear error messages, and serves as living documentation for your data formats. Libraries like Ajv (JavaScript), jsonschema (Python), and json-schema-validator (Java) make it straightforward to integrate schema validation into any application.
Performance Implications of JSON Size
The size of your JSON documents directly impacts application performance in several ways: network transfer time, parsing time, and memory consumption. Understanding these impacts helps you make informed decisions about JSON formatting and structure.
Network Transfer
Every byte of JSON must travel across the network from server to client. On fast connections, the difference between 10KB and 100KB may seem negligible, but on mobile networks or for users in regions with slower internet, the impact is significant. Studies show that each additional 100ms of load time reduces conversion rates by approximately 1%. Minification typically reduces JSON size by 30-50%, and gzip compression reduces it by an additional 70-85%. Always enable gzip or Brotli compression for JSON API responses.
Parsing Performance
JSON parsing is surprisingly expensive. For large documents (over 1MB), parsing can take hundreds of milliseconds on mobile devices. The cost scales roughly linearly with document size. Key strategies for reducing parsing cost include: sending only the data the client needs (field filtering), paginating large result sets, and using more efficient serialization formats like Protocol Buffers or MessagePack for internal service-to-service communication where human readability is not required.
Memory Usage
Parsed JSON typically consumes 3-10x more memory than its serialized form because each value becomes a separate object with its own memory allocation. A 1MB JSON string might use 5-10MB of RAM after parsing. For JavaScript applications running in browsers with limited memory, this can cause performance degradation or crashes on low-end devices.
JSON vs JSONL
JSON Lines (JSONL or NDJSON) is a related format that addresses one of JSON's key limitations: the requirement to parse the entire document as a single unit. In JSONL, each line of a file is a complete, independent JSON object.
When to Use JSONL
- Log files: Each log entry is a self-contained JSON object on its own line. You can append new entries without modifying existing data, and you can read any line independently.
- Data streaming: Process records as they arrive without waiting for the complete dataset. Each line is a complete message.
- Large datasets: Parse and process records one at a time without loading the entire file into memory. This is essential for datasets that exceed available RAM.
- Parallel processing: Split a JSONL file at line boundaries and distribute chunks to different workers. This is impossible with standard JSON, where splitting at arbitrary byte positions would break the structure.
When to Stick with Standard JSON
- API responses: Standard JSON is the expected format for REST APIs. Wrapping results in an array or object is conventional and expected.
- Configuration files: Configuration typically needs to be loaded all at once, so the streaming advantage of JSONL is irrelevant.
- Nested data structures: If your data has complex nesting that cannot be easily flattened into individual records, standard JSON is more natural.
Working with Large JSON Files
Large JSON files (over 10MB) present unique challenges that require special handling. Standard parsing approaches can fail or perform poorly at this scale.
Streaming Parsers
Streaming (or SAX-style) parsers process JSON incrementally without loading the entire document into memory. They emit events as they encounter structural elements like object starts, key-value pairs, and array items. This approach uses constant memory regardless of file size. Libraries like oboe.js (JavaScript), ijson (Python), and Jackson Streaming API (Java) provide streaming JSON parsing.
Practical Tips for Large Files
-
Convert to JSONL first: If you have a large JSON
array, converting it to JSONL (one object per line) enables
line-by-line processing with standard tools like
grep,awk, andjq. -
Use command-line tools:
jqis the standard tool for processing JSON from the command line. It can handle large files efficiently and supports streaming mode for very large inputs. - Split and parallelize: Break large JSONL files into smaller chunks and process them in parallel. Each chunk can be processed independently since each line is self-contained.
-
Avoid loading into memory: Never use
JSON.parse()on files larger than available memory. Use streaming parsers or process the file line by line. - Compress for storage: Large JSON files compress extremely well with gzip (typically 80-90% reduction). Keep compressed copies for storage and decompress on the fly during processing.
JSON Security Considerations
While JSON is a data format and not inherently insecure, the way applications handle JSON can introduce vulnerabilities. Understanding these risks is essential for building secure systems.
Never Use eval() to Parse JSON
The most critical security rule: never use JavaScript's
eval() function to parse JSON.
eval() executes arbitrary JavaScript code, which means a
malicious JSON payload could run code on the user's machine. Always
use JSON.parse(), which only parses valid JSON and
rejects any executable code. This is non-negotiable.
JSONP and Cross-Origin Risks
JSONP (JSON with Padding) was a technique for bypassing same-origin policy restrictions before CORS was widely supported. It works by wrapping JSON data in a function call that is executed as a script. This is inherently dangerous because it executes arbitrary JavaScript from a third-party server. If you control both the client and server, use CORS instead of JSONP. JSONP should be considered a legacy technique and avoided in new applications.
Prototype Pollution
When merging or deep-cloning JSON objects in JavaScript, be cautious
of keys like __proto__, constructor, and
prototype. If user-supplied JSON is recursively merged
into an existing object without sanitizing these keys, it can modify
the prototype of all objects in the application, leading to privilege
escalation or denial of service. Always sanitize object keys before
merging.
Denial of Service via Deep Nesting
A maliciously crafted JSON document with extreme nesting depth (thousands of levels) can cause stack overflow errors in recursive parsers. Mitigate this by setting a maximum nesting depth in your parser. Most production JSON parsers allow you to configure this limit.
Input Validation
Never trust JSON data from external sources. Always validate the structure, types, and value ranges of incoming JSON before using it. JSON Schema validation is the most robust approach, but even simple checks for required fields and type assertions provide significant protection against malformed or malicious input.
Need to format, validate, or minify JSON? Try our free online JSON tools. All processing happens in your browser for maximum speed and privacy.
JSON Formatter JSON ValidatorFrequently Asked Questions
What is the difference between pretty-printed and minified JSON?
Pretty-printed JSON includes whitespace (indentation, line breaks) for human readability, while minified JSON removes all unnecessary whitespace to minimize file size. Use pretty-printed JSON during development and debugging, and minified JSON in production for smaller network payloads and faster parsing.
What are the most common JSON formatting mistakes?
The most common mistakes are: trailing commas after the last item in an object or array, using single quotes instead of double quotes for strings, adding comments (JSON does not support comments), using unquoted object keys, and including undefined or NaN values which are not valid JSON.
When should I use JSONL instead of JSON?
Use JSONL (JSON Lines) when you need to process records incrementally, such as log files, data streams, or large datasets that do not fit in memory. Each line is a complete JSON object, so you can read and parse one line at a time without loading the entire file. Standard JSON requires parsing the complete document before any data can be accessed.
How can I validate JSON against a schema?
Use JSON Schema to define the expected structure of your JSON data, then validate instances against that schema using libraries like Ajv (JavaScript), jsonschema (Python), or online validators. JSON Schema lets you specify required fields, types, value ranges, string patterns, and nested object structures.
Is JSON secure for data exchange?
JSON itself is a data format and is neither secure nor insecure. However, how you parse and use JSON can introduce vulnerabilities. The main risk is using eval() to parse JSON (never do this �?always use JSON.parse()). Also be cautious with JSONP, which can bypass same-origin policies. Always validate and sanitize JSON data from untrusted sources before using it.