JSON Parser
Parse a payload and see its types, depth, key count and every path.
Nothing you paste leaves your browser. The connect-src allowlist makes that a browser guarantee rather than a promise. Check it yourself
Parsing turns text into structure. This page shows you what came out: the types, the nesting depth, how many keys and arrays there are, which numbers will not survive a JavaScript parser, and where any duplicate keys are.
It is the page to open when you have been handed a payload and the first question is what is actually in this.
What the statistics tell you
Each of these answers a question that comes up when you are about to write code against a document.
- Maximum depth
- How far the nesting goes. Above a few hundred levels, check what your consumers do. Measured here: V8 parses a million levels but refuses to serialise past about 4,800, and CPython’s C scanner manages around 17,000 despite a Python recursion limit of 1,000.
- Key count and object count
- A rough measure of how much work a mapper or an ORM will do, and of how large the tree will be in memory.
- Unsafe numbers
- How many integers exceed 2^53-1. If this is not zero, any JavaScript consumer is already reading different values from the ones in the file.
- Duplicate keys
- How many object keys were defined twice, with the position of each.
Parsing is not the same as validating a shape
A document can parse perfectly and still be useless to you: a field renamed, a number sent as a string, an array where an object was expected. Parsing checks the grammar, not the contract.
For the contract, generate a JSON Schema from a payload you trust and validate future payloads against it.
How this parser differs from JSON.parse
It is iterative rather than recursive, so nesting depth is bounded only by memory. It records the exact source text of every number, so nothing is silently rounded. It tracks the position of every token, so errors have a line and a column. And it recovers after an error rather than stopping, so a broken document reports every problem in one pass.
The cost of all that is speed: roughly 12 to 16 MB per second here against 60 to 70 for a native JSON.parse. That is the price of the information, and it is why the work runs in a background worker.
How to do this in code
Parsing in code, including the options people usually discover too late.
js JavaScript
The reviver cannot recover the original digits: by the time it runs the number has already been converted to a float.
const value = JSON.parse(text);
// The reviver runs on every key and value, which is how you
// intercept large integers before precision is lost.
const value2 = JSON.parse(text, function (key, val) {
if (typeof val === 'number' && !Number.isSafeInteger(val)) {
// this[key] is the raw value; the original TEXT is not
// available here, which is the limitation.
console.warn('unsafe integer at', key);
}
return val;
}); py Python
object_pairs_hook is the only portable way to detect duplicate keys in Python.
import json
from decimal import Decimal
# parse_float and parse_int receive the raw TEXT of the number,
# so unlike JavaScript you can keep full precision.
data = json.loads(text, parse_float=Decimal, parse_int=int)
# Detect duplicate keys instead of silently keeping the last
def no_dupes(pairs):
seen = {}
for k, v in pairs:
if k in seen:
raise ValueError(f'duplicate key: {k}')
seen[k] = v
return seen
data = json.loads(text, object_pairs_hook=no_dupes) go Go
// UseNumber keeps the original text instead of converting
// to float64, so large integers survive.
dec := json.NewDecoder(bytes.NewReader(data))
dec.UseNumber()
var v any
if err := dec.Decode(&v); err != nil {
return err
} java Java
ObjectMapper mapper = new ObjectMapper();
// Fail loudly on duplicates rather than keeping the last one
mapper.enable(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY);
// Keep big integers exact
mapper.enable(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS); Questions
- Why is my number different after parsing?
- Because JSON numbers have no size limit and IEEE 754 doubles do. Any integer above 2^53-1 and many decimals cannot be represented exactly. Python, Go and Java all offer a way to keep the original text; JavaScript does not, which is why large IDs should be sent as strings.
- What happens to duplicate keys?
- RFC 8259 leaves it undefined. JavaScript and Python keep the last occurrence, some Go and Java configurations reject the document, and a few parsers keep the first. Never rely on it. This page reports every duplicate with both positions.