Home / Blog / How to Format JSON in Python
How to Format JSON in Python: Complete Guide 2026
Last updated: May 16, 2026 · 10 min read
Formatting JSON in Python is one of the most common tasks developers face daily. Whether you're debugging API responses, saving configuration files, or generating readable data exports, Python's built-in json module makes it straightforward. This guide covers everything from basic pretty printing to advanced custom encoders.
Quick Tip: Need to format JSON right now without writing code? Try our free Online JSON Formatter — paste your JSON and get perfectly formatted output instantly.
Basic JSON Formatting with json.dumps
The simplest way to format JSON in Python is using json.dumps() with the indent parameter. This function converts a Python object to a JSON-formatted string.
import json
data = {
"name": "Alice",
"age": 30,
"skills": ["Python", "JavaScript", "Go"],
"address": {
"city": "Shanghai",
"country": "China"
}
}
# Pretty print with 2-space indentation
formatted = json.dumps(data, indent=2)
print(formatted)
The output will be a nicely formatted JSON string:
{
"name": "Alice",
"age": 30,
"skills": [
"Python",
"JavaScript",
"Go"
],
"address": {
"city": "Shanghai",
"country": "China"
}
}
Understanding the indent Parameter
The indent parameter controls the number of spaces used for each level of nesting. Common values are:
indent=None— Compact output, no whitespace (default)indent=2— 2 spaces per level (most common in web development)indent=4— 4 spaces per level (common in Python projects)indent='\t'— Use tabs instead of spaces
# Compact (default)
json.dumps(data)
# '{"name": "Alice", "age": 30, ...}'
# Tab indentation
json.dumps(data, indent='\t')
# '{\n\t"name": "Alice",\n\t"age": 30,\n\t...
'
Sorting Keys with sort_keys
For consistent, deterministic output — especially useful in testing and version control — use the sort_keys parameter:
formatted = json.dumps(data, indent=2, sort_keys=True)
print(formatted)
This sorts all keys alphabetically at every level of nesting, making it easier to compare JSON outputs across runs.
Writing JSON to a File with json.dump
While json.dumps() returns a string, json.dump() writes directly to a file object. This is more memory-efficient for large datasets:
import json
data = {
"users": [
{"id": 1, "name": "Bob"},
{"id": 2, "name": "Charlie"}
],
"total": 2
}
# Write formatted JSON to file
with open("output.json", "w", encoding="utf-8") as f:
json.dump(data, f, indent=2, ensure_ascii=False)
print("JSON written to output.json")
Important: Always use ensure_ascii=False when your data contains non-ASCII characters (Chinese, Japanese, emojis, etc.). Without it, characters like 你好 will be escaped as \u4f60\u597d.
Handling Non-Serializable Types
Python's json module can only serialize basic types: str, int, float, bool, None, list, and dict. For other types, you need a custom encoder.
Handling datetime Objects
This is the most common case. Python's datetime objects aren't JSON-serializable by default:
import json
from datetime import datetime, date
class DateTimeEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.isoformat()
if isinstance(obj, date):
return obj.isoformat()
return super().default(obj)
data = {
"event": "Python Conference",
"date": datetime(2026, 6, 15, 9, 0),
"created": date(2026, 1, 1)
}
formatted = json.dumps(data, indent=2, cls=DateTimeEncoder)
print(formatted)
Output:
{
"event": "Python Conference",
"date": "2026-06-15T09:00:00",
"created": "2026-01-01"
}
Handling Decimal and Other Numeric Types
import json
from decimal import Decimal
class SmartEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Decimal):
return float(obj)
if isinstance(obj, set):
return list(obj)
if isinstance(obj, bytes):
return obj.decode("utf-8")
return super().default(obj)
data = {
"price": Decimal("19.99"),
"tags": {"python", "json", "tutorial"},
"content": b"Hello World"
}
print(json.dumps(data, indent=2, cls=SmartEncoder))
Using the default Parameter (Simpler Approach)
For one-off cases, you can pass a function directly to the default parameter instead of creating a full encoder class:
import json
from datetime import datetime
def serialize(obj):
if isinstance(obj, datetime):
return obj.isoformat()
raise TypeError(f"Type {type(obj)} not serializable")
data = {"timestamp": datetime.now()}
print(json.dumps(data, default=serialize))
Controlling Output Format
Custom Separators
The separators parameter lets you control the separator between items. The default is (', ', ': ') for pretty output. For compact output matching JavaScript's JSON.stringify:
# Compact like JavaScript's JSON.stringify
compact = json.dumps(data, separators=(',', ':'))
# '{"name":"Alice","age":30}'
# Custom separators
custom = json.dumps(data, separators=(' | ', ' = '))
# '{"name" = "Alice" | "age" = 30}'
Handling Non-ASCII Characters
data = {"greeting": "你好世界", "emoji": "🐍"}
# Default: escapes non-ASCII
print(json.dumps(data))
# {"greeting": "\u4f60\u597d\u4e16\u754c", "emoji": "\ud83d\udc0d"}
# With ensure_ascii=False: preserves Unicode
print(json.dumps(data, ensure_ascii=False, indent=2))
# {
# "greeting": "你好世界",
# "emoji": "🐍"
# }
Reading and Formatting Existing JSON Files
A common workflow is reading a JSON file, possibly modifying it, and writing it back in a formatted way:
import json
# Read, format, and rewrite
with open("config.json", "r", encoding="utf-8") as f:
data = json.load(f)
# Optionally modify the data
data["last_modified"] = "2026-05-16"
# Write back with formatting
with open("config.json", "w", encoding="utf-8") as f:
json.dump(data, f, indent=2, ensure_ascii=False, sort_keys=True)
Advanced: Pretty Print JSON from a String
If you already have a JSON string (e.g., from an API response) and want to format it:
import json
raw_json = '{"name":"Alice","age":30,"skills":["Python","JS"]}'
# Parse and re-format
parsed = json.loads(raw_json)
formatted = json.dumps(parsed, indent=2)
print(formatted)
Format JSON from Command Line
You can use Python as a quick JSON formatter from the terminal:
# Format a JSON file
python -m json.tool input.json
# Format and save
python -m json.tool input.json > formatted.json
# Format from a pipe
echo '{"a":1,"b":2}' | python -m json.tool
# With indentation
python -m json.tool --indent 4 input.json
# Sort keys
python -m json.tool --sort-keys input.json
Performance Considerations
For large JSON files, keep these tips in mind:
- Use
json.dump()with file objects instead ofjson.dumps()+ file write for large data - Setting
indent=None(default) produces the smallest output sort_keys=Trueadds sorting overhead — skip it if ordering doesn't matter- For very large files (100MB+), consider streaming with
ijsonlibrary
Comparison: json.dumps vs json.dump
json.dumps(obj)— Returns a JSON stringjson.dump(obj, file)— Writes JSON directly to a file
import json
data = {"key": "value"}
# Returns string
json_string = json.dumps(data, indent=2)
# Writes to file
with open("out.json", "w") as f:
json.dump(data, f, indent=2)
Common json.dumps Parameters Reference
indent— Number of spaces for indentation (or tab character)sort_keys—Trueto sort keys alphabeticallyensure_ascii—Falseto preserve Unicode charactersseparators— Tuple of(item_separator, key_separator)default— Function for non-serializable objectscls— Custom JSONEncoder subclassskipkeys—Trueto skip non-string keys instead of raising TypeError
Frequently Asked Questions
How do I pretty print JSON in Python?
Use json.dumps(data, indent=2) to get a formatted JSON string. For printing to console, you can also use pprint module, but json.dumps with indent gives proper JSON formatting.
What is the difference between json.dumps and json.dump?
json.dumps() returns a JSON-formatted string. json.dump() writes JSON directly to a file object. Use dumps when you need a string, dump when writing to a file.
How do I format JSON with 4 spaces in Python?
Pass indent=4 to json.dumps(): json.dumps(data, indent=4).
How do I handle datetime objects in JSON?
Create a custom encoder class that inherits from json.JSONEncoder and override the default method to convert datetime objects to ISO format strings. Pass it as cls=YourEncoder to json.dumps().
Why are my Chinese/Unicode characters escaped in JSON output?
By default, json.dumps sets ensure_ascii=True, which escapes non-ASCII characters. Pass ensure_ascii=False to preserve them.
How do I format JSON from the command line?
Use Python's built-in module: python -m json.tool input.json. Add --sort-keys for sorted output and --indent 4 for custom indentation.
Try It Online
Don't want to write code just to format JSON? Use our free online JSON Formatter — paste your JSON, choose your indentation, and get formatted output instantly. No signup required.