Formatter Validator Minifier Escape / Unescape JSON ↔ String JSON ↔ YAML JSON → CSV NDJSON / JSON Lines JSON → Types JSON ↔ XML JSON Diff JSON Patch Canonicalize (RFC 8785) Schema Validator Schema Generator JSONPath Tester JWT Decoder JSON Errors Schemas More Tools
136 questions · searchable

Frequently Asked Questions

Everything about the tools on this site — privacy, limits, standards, and the behaviour that surprises people. Where an answer quotes a number, it comes from a measurement in this repository rather than an impression.

JSON basics

JSON (JavaScript Object Notation) is a way to write down structured data so that any program can read it. It uses three main shapes: objects (key-value pairs wrapped in {}), arrays (lists wrapped in []), and primitive values (strings, numbers, booleans, null). Despite the JavaScript in the name, JSON is supported by every modern programming language. It's the default data format for most web APIs and many configuration files.
JSON is text — a specific syntax for representing data that any language can parse. JavaScript objects are live in-memory data structures that include methods, prototypes, and references. JSON is a subset: any valid JSON parses into a JavaScript object, but most JavaScript objects can't be represented as JSON (functions, undefined values, circular references, Symbol keys, and Dates all fail to serialize).
Yes — both keys and string values are case-sensitive. "name" and "Name" are different keys. This is a common source of bugs when consuming JSON: an API documents a field as customerId but actually returns customerID, and your code silently fails to find it. Pretty-printing the JSON and inspecting it with the formatter is the fastest way to catch these mismatches.
Six types: string (double-quoted text), number (integer or floating-point), boolean (true or false), null, object (unordered key-value pairs), and array (ordered list). Notably missing: dates (use ISO 8601 strings), binary data (use Base64-encoded strings), and big integers above 2^53 (use strings to preserve precision).
No. Standard JSON does not support comments — neither // line comments nor /* block comments */. There are non-standard supersets that do: JSONC (JSON with Comments, used by VS Code) and JSON5 (a more flexible superset). If you need comments in a config file, choose one of those — but the receiving tool must support the format. Our tools strictly validate against standard JSON.
The most common culprits, in order of frequency: (1) trailing commas — a comma right before a closing brace or bracket; valid JavaScript but not JSON. (2) single quotes instead of double quotes — JSON requires double quotes everywhere. (3) unquoted object keys — every key must be in double quotes. (4) comments — JSON has no comment syntax. (5) invisible characters like a UTF-8 BOM at the start, or smart quotes pasted from a word processor instead of straight ASCII quotes.
The error message names the specific token the parser didn't expect, and our tools also report the line and column. Common cases: 'Unexpected token }' usually means a missing comma between properties or a trailing comma. 'Unexpected token :' usually means an unquoted key. 'Unexpected end of JSON input' means a missing closing brace or bracket. Look at the line/column the error points to and the character just before it — that's almost always where the real problem is.
Historical reasons. JSON was designed in 2001 as a strict subset of JavaScript object literal syntax, and at the time, JavaScript itself was inconsistent about trailing commas (different engines treated them differently). Douglas Crockford chose strictness for maximum portability. Modern JavaScript allows trailing commas, but JSON's spec was already in wide use and couldn't be loosened without breaking implementations. JSON5 and JSONC both allow trailing commas — switch to those if you need them.
Most JSON parsers hit the call stack limit around 500-2000 levels deep, depending on the runtime. This usually indicates a bug in the program generating the JSON — real data rarely needs more than 10-20 levels of nesting. If your structure is genuinely that deep, consider flattening it (use composite keys like "a.b.c.d" instead of {a:{b:{c:{d:1}}}}) or splitting it across multiple documents linked by ID.
Comfortably up to 50 MB on modern browsers. Between 50 MB and 100 MB, expect noticeable lag — the tools still work, but pasting and formatting take longer. Above 100 MB, the browser's memory limits become a problem and we'd recommend a command-line tool like jq instead, which can stream gigabyte-scale files.
Browser JavaScript runs on a single thread. While the tool is parsing and formatting, the UI can't repaint or respond. For files under 10 MB, this is imperceptible. For larger files, you'll see the tab become unresponsive for a few seconds. If your file is too big to handle comfortably in the browser, use jq or a language-specific streaming parser.
Faster than most online formatters because we use the browser's native JSON.parse and JSON.stringify rather than a JavaScript reimplementation. Native parsing is typically 5-10x faster than a JS-implemented parser. For a 10 MB JSON file, formatting completes in well under a second on modern hardware.
Not currently. We strictly validate standard JSON per RFC 8259. JSON5 allows comments, trailing commas, unquoted keys, and other relaxations; JSONC (used in VS Code config files) is essentially JSON5 lite. Native JSON5/JSONC support is on our roadmap — for now, strip comments and convert single quotes to double quotes before pasting.
We deliberately don't store anything server-side, so there's no shareable URL with your data baked in. To share, copy the formatted JSON and paste it into a gist (gist.github.com), Pastebin, or any paste service. Avoid pasting sensitive JSON to public services — for that, share via a private channel.
No, and intentionally so. The value of this site is browser-side processing without an API call. For programmatic use, every language has built-in JSON support: JSON.stringify(obj, null, 2) in JavaScript, json.dumps(obj, indent=2) in Python, json.MarshalIndent in Go, serde_json::to_string_pretty in Rust. For CLI work, jq is the standard.
Functionally similar — all of them format, validate, and convert JSON. The differences worth knowing: (1) most competitor sites send your JSON to their server for processing; ours doesn't. (2) Our error reporting is line/column precise. (3) Our interface is uncluttered with no ads inside the tool itself. (4) The site loads faster because we don't use heavy front-end frameworks. If privacy and speed matter to you, we'd argue ours is the better choice.
JSON Schema is a way to describe the structure of JSON data — required fields, types, allowed values, regex patterns, ranges. Think of it as a type system for JSON. Use it when you need to validate inputs (incoming API requests), document outputs (API responses), generate type definitions, or auto-generate tests. Our JSON Schema Validator handles this. JSON Schema is the foundation of OpenAPI and AsyncAPI.
JSONPath is a path query language for JSON — like XPath for XML. $.users[*].email extracts every user's email. jq is a more powerful language that can also transform and aggregate data, not just select. For simple extraction, JSONPath is easier to learn; for complex pipelines, jq is more capable. Our JSONPath tester uses the Goessner dialect, supported by most JSON libraries.
Both operate on the same data — only the whitespace differs. Formatting (also called pretty-printing or beautifying) adds indentation, newlines, and spaces so humans can read the JSON. Minification removes all unnecessary whitespace to produce the smallest valid representation, typically 30-60% smaller. Use formatting during development; use minification for production APIs, storage, and over-the-wire transmission.
Depends on who's editing them. YAML is easier to write by hand (less punctuation, comments allowed) and is the standard for Kubernetes, GitHub Actions, Docker Compose, and Ansible. JSON is easier to generate programmatically and faster to parse. For configs that humans edit frequently, YAML wins. For configs that programs generate and consume, JSON wins. Our JSON ↔ YAML converter lets you switch between them.
Yes — our JSON to CSV converter flattens nested objects using dot notation. {"user":{"name":"Alice"}} becomes a CSV column called user.name. Arrays inside objects are preserved as JSON strings in a single cell, keeping the information intact without breaking the row-to-row correspondence.
Use our JSON Diff tool. It does semantic comparison — key order doesn't matter, whitespace doesn't matter, only real data differences are reported. Each difference is labeled with a JSON path like $.users[2].email so you can navigate directly to it. This is much more accurate than text-based diff for JSON.
Fully supported. JSON strings can contain any Unicode character including emoji, CJK characters, and right-to-left scripts. Our tools use the browser's native parser which is fully Unicode-aware. Characters outside the Basic Multilingual Plane (like emoji) are typically represented as surrogate pairs in JSON — both forms (raw character and \uD83D\uDE00 escape) round-trip correctly.
JavaScript stores all numbers as 64-bit IEEE 754 floats, which means integers larger than 2^53 (about 9 quadrillion) lose precision when parsed. This is a JavaScript limitation, not a tool limitation. If your JSON contains huge integer IDs like Twitter snowflake IDs or 64-bit database IDs, store them as strings ("id": "123456789012345678") to preserve precision.
JSON has no native date type — dates are conventionally stored as ISO 8601 strings ("2026-05-13T12:34:56Z") or Unix timestamps (1747140896). The formatter preserves whichever representation you use as plain strings or numbers. For JWT tokens, our JWT decoder automatically converts Unix timestamps in iat, exp, and nbf claims to human-readable times.
JSON technically allows duplicate keys — the spec doesn't forbid them, though it warns that behavior is undefined. Most parsers silently keep only the last value for a duplicate key, which is what JavaScript's JSON.parse does. If you see this happening, the original data has duplicate keys; check the source. Our tools don't flag duplicates because they're valid JSON, but they're almost always a bug.
Not currently — our Schema validator requires you to paste both the schema and the data. We don't fetch external $ref URLs because that would require network requests, which contradicts our privacy-first design. To validate against a schema-by-URL, inline the schema first with a tool like json-dereference-cli.

Formatting & validating

Both parse your JSON and report the same errors. The Formatter is built around producing readable output, so it leads with the indented result. The Validator is built around the verdict, so it leads with valid or invalid and the exact location. If you only want to know whether a document parses, use the Validator — on a large file it does strictly less work and uses no memory for output.
Two spaces, four spaces, and tabs. Two is the default because it is what JSON.stringify(x, null, 2) produces and what most style guides assume. Tabs are worth choosing if your team's editor config uses them, since mixing the two in one repository causes noisy diffs.
No. Formatting only adds or removes insignificant whitespace between tokens. Every string, number literal, key order and structure is preserved byte for byte. Our streaming formatter copies number literals verbatim, so 9223372036854775807 stays exactly that rather than being rounded — which is not true of tools that parse to an object and re-serialise.
Almost always number normalisation. A tool that parses to a native object and re-serialises turns 1e2 into 100 and 1.0 into 1, and rounds any integer beyond 253−1. We copy the original literal instead. See which languages silently corrupt large JSON numbers.
Not in the formatter, deliberately — reordering keys changes the document, and JSON object member order is not significant but is often meaningful to humans reading a diff. If you need a deterministic key order for hashing or signing, use the canonicalizer, which sorts keys as RFC 8785 requires.
It attempts common mechanical fixes — removing trailing commas, converting single quotes to double quotes, quoting unquoted keys, and stripping comments. It is a convenience for hand-edited files, not a parser. Always check the result: repair cannot know whether a missing comma belonged before or after the line it guessed.
Pasting is limited by what your browser can hold in a textarea, which starts to struggle well before 10 MB. Above 4 MB, upload the file instead — it switches to the streaming reader and handles up to 100 MB without loading the document into memory.
Yes. Beautifier, formatter and pretty-printer all describe the same operation: taking JSON and re-laying it out with indentation and line breaks so a person can read it. The terms come from different tools rather than from any difference in what they do, and none of them appears in RFC 8259 — the standard has nothing to say about whitespace beyond permitting it between tokens. The formatter on this site is the beautifier; there is no separate tool to look for.
It should not, and here it does not. Whitespace between tokens carries no meaning in JSON, so adding it cannot change a value. The catch is how a tool does it: most parse the document into memory and re-serialise it, which quietly rounds a large integer such as 9223372036854775807 and rewrites 1e10 as 10000000000. This formatter re-emits the original text and copies every number literal verbatim, so the only thing that changes is the whitespace.

Errors & troubleshooting

A reference mapping the exact error message your parser printed back to the mistake that caused it. It holds 1,050 error strings captured by running 50 malformed documents through 21 parsers across 12 runtimes — not transcribed from documentation, but recorded from actual execution. Search your message.
Because every parser words it differently, and V8 changed its own wording in Node 20. A trailing comma is Expected double-quoted property name in JSON at position 8 in Chrome, JSON.parse: expected double-quoted property name… in Firefox, and JSON Parse error: Property name must be a string literal in Safari. Side by side.
You received HTML, not JSON — almost always a server error page, a login redirect, or a proxy interstitial. The JSON is not malformed; there is no JSON. Check the HTTP status and Content-Type before parsing, and log the first 200 characters of the body so the real page shows up in your logs.
Usually a UTF-8 byte order mark. Windows editors, Excel exports and PowerShell's Out-File add one by default, and it is invisible in your editor. RFC 8259 §8.1 says a JSON text must not begin with one. Check with head -c 3 file.json | xxd.
Because nothing is required to. RFC 8259 §4 says member names should be unique, not must, and leaves the result undefined. All 21 parsers we tested accept it; most keep the last value, and System.Text.Json keeps both. There is no parse error to catch — you have to look for it deliberately.
Ours, yes — they are computed from the byte offset against a newline index. But note that a reported position often points at the token after the problem. A missing comma is reported at the start of the next key, so look one token to the left of wherever you land.
Your editor is probably showing you JSONC or JSON5, not JSON. RFC 8259 §4 and §5 give the object and array grammar with no trailing separator. tsconfig.json and VS Code settings are JSONC, which is why comments and trailing commas work there and nowhere else.
No. JSON has no comment syntax at all — RFC 8259 §2 lists the complete token set, and comments are not in it. If you need them, you want JSONC or JSON5 and a parser for that dialect. The common workaround is a "_comment" key, which is ugly but survives every parser.

Numbers & precision

It exceeded 253−1. JSON permits arbitrary-precision numbers, but most parsers map them to an IEEE 754 double, which holds integers exactly only up to that point. A Snowflake ID such as 1541815603606036480 comes back as 1541815603606036500 in every JavaScript engine and in Go. No error is raised.
Measured across 11 parsers: Java (Jackson, Gson), .NET (System.Text.Json, Newtonsoft), Ruby and Python preserve it. Every JavaScript engine and Go's encoding/json round it. Full table.
As strings. If a value can exceed 253−1 it is an identifier rather than a quantity, and belongs in quotes. This is why Twitter's API has always returned both id and id_str. If you cannot change the producer, use a precision-preserving parser: json-bigint in JavaScript, parse_int= in Python, json.Number in Go.
The formatter and minifier do not — they copy number literals verbatim, so nothing changes. The canonicalizer must, because RFC 8785 is defined in terms of ECMAScript number serialization, and it warns you when it does. The type generator flags any field that exceeds the safe range.
No. RFC 8259 §6 says values that cannot be represented in its number grammar — Infinity and NaN among them — are not permitted. Python's json.dumps emits them by default, which is why they reach production: a round trip inside Python succeeds while every other language rejects the output. Pass allow_nan=False to catch it at write time.
That is IEEE 754 binary floating point, not JSON. The JSON text is exact; the double you parse it into is not. If you are handling money, carry amounts as integer minor units or as strings, and never as JSON floats.

Escaping

Three things, per RFC 8259 §7: the quotation mark, the reverse solidus, and the control characters U+0000–U+001F. Everything else is optional. Every difference you see between serializers is a choice they made beyond that minimum.
json.Marshal escapes them to \u003c, \u003e and \u0026 so JSON embedded in HTML cannot be reinterpreted as markup. Use an Encoder with SetEscapeHTML(false) to stop it. Go's encoding/json/v2 drops this default.
json.dumps() defaults to ensure_ascii=True, escaping every non-ASCII character. Pass ensure_ascii=False for UTF-8 output. Both are valid and represent the same string — they are just not byte-identical, which matters if you are diffing or hashing.
Usually the apostrophe. Gson escapes ' to \u0027 and Jackson does not. Gson also escapes HTML-significant characters. Measured side by side on the escape tool page.
LINE SEPARATOR. RFC 8259 §12 notes it is legal in JSON but illegal in JavaScript, so JSON containing it can break a <script> block. Go, .NET, PHP and Newtonsoft escape it; the JavaScript engines and Jackson do not. Modern engines accept it in string literals since ES2019, but older consumers may not.
Yes — that is what the presets are for. Each one reproduces the measured default output of a specific serializer: Python's json.dumps(), Go's encoding/json, System.Text.Json, PHP's json_encode, Gson. All 130 preset outputs are verified byte for byte against the real serializer.
No. RFC 8259 §7 permits \/ but never requires it. PHP's json_encode does it by default; add JSON_UNESCAPED_SLASHES to stop it. It is a hangover from embedding JSON in HTML, where </script> inside a string could end the block early.
Characters outside the Basic Multilingual Plane — emoji, mostly — are encoded as a UTF-16 surrogate pair. Slicing a string by code unit can cut one in half, leaving a high surrogate with no partner. RFC 8259 §8.2 calls the behaviour of receiving software unpredictable. Our unescape tool rejects it rather than guessing.

Large files

100 MB for validating, formatting and minifying, which stream. Tools that need the parsed values in memory — the JSONPath tester, schema validator and diff — cap near 20 MB. We publish both numbers rather than one headline figure, because a single number would be wrong for half the tools.
By never building an object. A byte-level scanner reads the file in chunks inside a Web Worker, tracks only the container nesting, and writes formatted output straight to a Blob. Measured on a 101 MB file: 620 ms and about 1 MB of heap, against 2.9 s and 299 MB for JSON.parse. Full numbers in the benchmark.
No. Upload is the browser's word for choosing a local file. The bytes are read by JavaScript on your machine through the File API and never leave it. You can confirm this in your browser's Network tab: no request is made when you select a file.
Rendering 100 MB of syntax-highlighted text would use several gigabytes — rendering, not parsing, is what kills the tab at that size. We show the first 200 KB as a preview and give you the full result as a download.
No. Scanning stops at the first syntax error, which is why the panel tells you how much was read. On a 101 MB file with a trailing comma at 85%, we report the line and column in 412 ms having read 86 MB. A tool built on JSON.parse must load the whole document before it can say anything.
It needs Web Workers and Blob.stream() — Chrome 76+, Firefox 69+, Safari 14.1+. On anything older we tell you plainly rather than falling back to the method that would freeze the tab.
Yes. The test file generator builds a file of any size from 5 MB to 150 MB in your browser, valid or deliberately broken. The 150 MB option exists specifically so you can see the refusal message work.
Formatting 100 MB produces roughly 180 MB of output, which a browser can hold as a Blob but not comfortably as a single JavaScript string — V8 caps strings near 512 MB. Rather than fail unpredictably somewhere above that, we stop at a number we have actually tested. For larger files, a command-line tool such as jq is the right instrument.

JSON Schema

draft-07 and 2020-12, scored against the official JSON-Schema-Test-Suite: 904/906 for draft-07 and 1221/1226 for 2020-12. Those figures exclude two categories we do not implement and report as errors rather than skipping — remote $ref URLs, which need network access a browser tool cannot make, and $dynamicRef. Across every test in the suite including those, the raw figures are 915/929 and 1244/1301.
Because valid can be misleading if part of your schema was never applied. If you use prefixItems under draft-07, or misspell a keyword, that constraint does nothing — and no validator is required to tell you. We list every keyword that is not being enforced so valid never quietly means partly checked.
In draft-07, $ref replaces the entire schema object, so any sibling keyword is discarded. Write {"$ref": "#/$defs/user", "minProperties": 3} and the minProperties rule does nothing. We audited all 646 schemas in the SchemaStore catalogue and 133 of them do this, including tsconfig.json.
No, and it says so rather than skipping it. Everything runs in your browser, so an external URL cannot be resolved. Bundle the referenced schema into $defs, or inline it. A validator that silently ignored an unresolvable reference would report valid for a document it never fully checked.
Either it declares $schema for draft-07, or it declares nothing and we inferred the draft from the keywords it uses. The draft selector lets you override it, and the result always states which draft was applied. Add $schema to your schema to remove the ambiguity.
By default here, yes — but the specification says format is an annotation, not an assertion, and implementations vary wildly. The toggle lets you switch to spec-strict behaviour. Do not rely on format for security-relevant validation in any implementation.
It publishes a field-by-field reference for 249 real-world schemas — package.json, tsconfig, GitHub Actions, Docker Compose and others — generated from the schemas themselves, each with our validator preloaded so you can check your own file. Browse it.
Because a page that lists six undocumented properties helps nobody. We publish schemas with at least eight properties, at least 70% of them carrying descriptions, and a filename pattern to match — the ones where a generated reference is worth reading.
$dynamicRef and $dynamicAnchor, and remote $ref URLs. Both are reported as errors rather than passed over. Everything else in draft-07 and 2020-12 is implemented, including unevaluatedProperties with full annotation collection across allOf, anyOf, $ref and if/then.

JSONPath

Yes. JSONPath became an IETF Standards Track document — RFC 9535 — in February 2024, and our tester scores 703/703 on the official Compliance Test Suite: 456/456 evaluation and 247/247 rejection of invalid queries. Most implementations predate the RFC and behave differently.
RFC 9535 §2.1 requires a conforming implementation to reject a query that does not match the grammar rather than guess. Expressions like $[], $.., $[0,] and $[@.a] are invalid and older tools accepted them. If you get a rejection, the query was never portable.
Because RFC 9535 comparisons are strictly typed — a string is never equal to a number. Pre-standard implementations often coerced, which quietly returned extra rows. If you want both, use $[?@.a=="1" || @.a==1].
The five the RFC defines: length(), count(), value(), match() and search(). The last two use I-Regexp (RFC 9485). Arguments are type-checked when the query is parsed, so a mistyped call is an error rather than a wrong result.
The canonical, unambiguous location of a matched node, defined in RFC 9535 §2.7 — for example $['users'][0]['name']. We show one for every match, and you can paste it straight back in as a query to select exactly that node.
No. JSONPath is a query language for selecting nodes; jq is a full transformation language with its own syntax, filters and output formatting. JSONPath expressions do not run in jq and vice versa. JSONPath is closer in scope to XPath for XML.

Patch & signing

JSON Patch (RFC 6902) is a list of operations addressing locations by JSON Pointer; Merge Patch (RFC 7386) is a document shaped like the target where null means delete. Measured over 39,000 changes, Merge Patch is smaller 96% of the time and cannot express 10% of changes at all. The comparison.
Because null already means remove this member, so there is no way to distinguish deletion from setting a null value. If your API has nullable fields, Merge Patch is the wrong format. Our generator detects the case and tells you instead of emitting a patch that quietly deletes the field.
No, and no tool can honestly claim that for arrays — several different patches correctly transform the same source into the same target. We compare array elements positionally and do not emit move or copy: those patches are shorter but harder to read. Every patch we produce is verified to reproduce the target exactly.
Optimistic concurrency. {"op":"test","path":"/version","value":7} asserts a value before the patch changes anything, and RFC 6902 §5 requires the whole patch to be atomic — so if the document has moved on, nothing is applied. No ETag, no lock, no extra round trip.
Hashing and signing. Two byte-different JSON documents can represent the same data, so a signature over raw bytes is meaningless. RFC 8785 defines an invariant serialization — no whitespace, keys sorted by UTF-16 code unit, ECMAScript number formatting, UTF-8 output — so the same data always produces the same bytes.
Yes, and this is the trap. Because RFC 8785 uses ECMAScript number serialization, {"id":9223372036854775807} canonicalizes to {"id":9223372036854776000}. A signature over the canonical form does not cover the number you sent. Our tool detects and reports every value that changes — carry large identifiers as strings.
It is grammatically valid JSON but outside the IEEE 754 double range, and RFC 8785 constrains input to I-JSON (RFC 7493), which does not permit it. There is no canonical form to produce. RFC 8259 §6 names 1E400 as exactly this interoperability problem.
crypto.subtle only exists in a secure context, so the digest needs https or localhost. On plain http the canonical form is still correct — only the hash is unavailable, and we say so rather than failing silently.

Converters

From JSON to YAML, yes — JSON is a subset of YAML 1.2. The other direction is not always: YAML has anchors, aliases, multiple documents per file, comments and non-string keys, none of which JSON can represent. Anything that cannot be expressed is reported rather than silently dropped.
Nested keys are joined with a dot, so {"user":{"name":"Ada"}} becomes a column user.name. Arrays of scalars are joined; arrays of objects cannot be flattened into a single row and are reported. CSV is a flat format, so any conversion from nested JSON loses structure by definition.
The header is the union of all keys across all records, and a record missing a key gets an empty cell. That keeps the row count honest — you can tell an absent field from an empty string by checking the source.
XML has no anonymous values: every value needs an element. Keys that are not valid XML names — anything starting with a digit, or containing a space — must be renamed, and array items need a repeated wrapper element. The converter picks sensible defaults and shows you what it chose.
Not yet. The honest reason is that CSV to JSON is ambiguous in ways JSON to CSV is not: every value is a string unless you infer types, and inference guesses wrong on zip codes, phone numbers and leading zeros. We would rather not ship a converter that quietly turns 01234 into 1234.

Type generation

TypeScript interfaces, Go structs, Python dataclasses, Rust serde structs, C# classes and Java classes with Jackson annotations. The output for a deliberately awkward sample is compiled on every change with tsc --strict, go build, CPython, cargo build, dotnet build and javac.
By presence. If a field is absent from any object in an array of samples, it becomes optional. If a field is ever null, it becomes nullable. These are different things and the generated types keep them separate.
You get the language's escape hatch — unknown, interface{}, Any, serde_json::Value — plus a warning naming the field. No correct concrete type exists, so guessing one would only move the failure to runtime.
Renamed safely and mapped back with the right annotation for each language: a json: tag in Go, #[serde(rename)] in Rust, [JsonPropertyName] in C#, @JsonProperty in Java. So user-name, 2fa and class all round-trip correctly.
It is one sample. A field absent from your sample will be absent from the types, and a field that happens to contain only whole numbers will be typed as an integer even if it can hold decimals. Paste the widest sample you have. For a guarantee rather than an inference, start from a JSON Schema.

JWT

No. It decodes and displays the header and payload so you can read the claims. Verification needs the signing key, and pasting a production signing key into any website is a bad idea. Verify in your own backend.
The decoding happens entirely in your browser and nothing is transmitted. That said, a JWT is a credential: if it is a live production token, treat pasting it anywhere as a decision worth thinking about, and rotate it if in doubt.
Because a JWT is signed, not encrypted. The header and payload are base64url-encoded, not secret. Anyone holding the token can read every claim. Never put anything confidential in a JWT payload.

Standards

Two, and they agree. RFC 8259 (STD 90, IETF, 2017) and ECMA-404 2nd edition (Ecma International, 2017) define the same grammar using different formalisms. RFC 8259 additionally gives interoperability guidance that ECMA-404 does not. Both are normatively referenced by the other.
RFC 7493 — a restricted profile of JSON for maximum interoperability. It requires unique member names, UTF-8, and numbers within the IEEE 754 double range. RFC 8785 canonicalization requires I-JSON input, which is why canonicalizing a document with duplicate keys or a 64-bit integer is a problem.
Yes. RFC 8259 §2 defines a JSON text as a single value with optional whitespace, so "hello", 42 and true are all complete JSON documents. Earlier specifications required an object or array at the top level, which is why some older parsers reject them.
For anything exchanged between systems, yes — RFC 8259 §8.1 requires it. Earlier specifications allowed UTF-16 and UTF-32; in practice UTF-8 is the only encoding that achieves interoperability.
application/json, registered in RFC 8259 §11. No charset parameter is defined, because the encoding is already fixed as UTF-8. Related types exist for specific uses: application/json-patch+json, application/merge-patch+json, application/schema+json.
The specification says object member order is not significant, and RFC 8259 §4 notes that libraries differ on whether they expose it. In practice most parsers preserve insertion order, but relying on it makes your code dependent on an implementation detail. Use an array if order matters.
Not in the grammar. RFC 8259 §9 explicitly permits an implementation to set limits on nesting depth, text size, number range and string length. Deeply nested input from an untrusted source is a real availability risk — cap the depth at your API boundary rather than at the parser.

Practical advice

It helps less than most pages claim. Across 799 real documents, minifying saves a median 36% of raw bytes but only 11.6% once the response is gzipped — and almost every API is. Turning compression on is worth 82.8%. Minifying still matters for storage, logs and URL embedding.
Brotli, where you can. On already-minified JSON it saves a further median 17.8% over gzip — more than minifying saves on top of gzip. It is supported by every current browser.
JSON has no date type, so pick a convention and document it. RFC 3339 date-time strings — 2026-01-15T09:30:00Z — are the safest default: unambiguous, sortable as text, and supported by every language. Epoch integers are compact but hide the timezone question rather than answering it.
Be consistent, and prefer whichever your consumers can distinguish. Note that JSON Merge Patch cannot express set to null at all, so if your API uses Merge Patch, nullable fields will cause problems later. Omitting is generally safer for optional data; null is right when absence and emptiness mean different things.
Newline-delimited JSON — one complete document per line. Log pipelines, BigQuery exports and streaming APIs use it because a consumer can process one record at a time without loading the file. It is not a single JSON document, so a whole-document parser will reject it. Read it line by line.
Set an error handler that always responds with JSON and the right status code, and have clients check the status and Content-Type before parsing. Most 'Unexpected token <' incidents are a framework's default HTML error page escaping into an API route.
No. RFC 8259 §12 calls it an unacceptable security risk, since the text could contain executable code alongside data. It also does not work for all valid JSON: U+2028 and U+2029 are legal in JSON and illegal in JavaScript. Use JSON.parse.
Parse it, then validate its shape against a JSON Schema, then apply your own business rules. Also cap the request size and the nesting depth at the boundary — RFC 8259 §9 explicitly permits this, and unbounded nesting is a denial-of-service vector (CWE-674).
Compare parsed values rather than text, so formatting and key order do not cause false positives. If you need a machine-applicable result, generate an RFC 6902 patch — an empty patch means the documents are equivalent, and a non-empty one tells you exactly what changed.
No. Log one compact JSON object per line — NDJSON — so each entry is a single grep-able record and log shippers can parse it incrementally. Pretty-printing turns one event into dozens of lines and breaks line-based tooling.
Use a schema with description on every property, and point your editor at it — VS Code and JetBrains IDEs will show the descriptions inline. That gives you documentation that is machine-checkable, unlike comments. Our schema registry shows what a well-documented schema looks like.
Validate it first with a streaming tool to confirm it is well-formed, then extract what you need rather than opening the whole thing. Our formatter streams up to 100 MB; beyond that, jq with a filter or a streaming parser in your language of choice is the right approach.

Privacy & technical

Yes — every tool on this site runs entirely in your browser. JSON you paste, upload, or drop onto these pages is processed by JavaScript on your device. The website's server never sees your data because there is no server-side processing. To verify: open your browser's Developer Tools, switch to the Network tab, and use any tool. You'll see zero outbound requests carrying your data.
Completely free. No signup, no paywall, no usage limits, no premium tiers. The site is supported by ads in the page header and footer area — never inside the tool itself. Every feature is available to everyone, every time.
No JSON data is logged or stored. We use Google Analytics for anonymous pageview metrics (page URL, country-level location, browser type — nothing about the contents of your tool inputs). It has no access to your tool inputs. This site carries no advertising. Full details on our privacy page.
Yes. Once a tool page has loaded, you can disconnect from the internet and it keeps working. All parsing, formatting, validation, and conversion logic is JavaScript that executes locally. For truly air-gapped use, save the page with Ctrl+S / Cmd+S and you'll have a fully self-contained copy.
Yes — JWTs and API responses both stay in your browser. We specifically built the JWT decoder to decode tokens client-side without ever submitting them. We deliberately don't offer signature verification because that would require collecting your secret keys, and we won't ask for those.
The tools themselves set none. Anonymous analytics may set one. This site carries no advertising, so there are no advertising cookies, and nothing you paste into a tool is stored — in a cookie or anywhere else.
No. Both typefaces are self-hosted on this domain — two variable WOFF2 files, 88 KB in total. No request goes to fonts.googleapis.com or fonts.gstatic.com, which also removes an EU data-transfer question.
The tools work as long as the page loads, because processing is local. If your network blocks the analytics domain, the tools still function normally.
No. Every tool is client-side JavaScript with no backend, so there is nothing to expose as an API. For automation, the underlying formats are all standardised — use a library in your own language.
The JavaScript is not minified or obfuscated, so you can read every engine directly in your browser's dev tools — including the scanner, schema validator, JSONPath engine and canonicalizer. That is also how you can verify that nothing is transmitted.
Because a tool that tells you something is invalid should be able to show you the rule. Every error page cites the exact section of RFC 8259 or ECMA-404 that governs it, and every schema page cites the specification section for each keyword. Only standards bodies and peer-reviewed venues are cited.
Use the contact page. A wrong result is worth reporting even if it seems minor — the engines here are scored against official test suites precisely so that disagreements can be investigated rather than argued about.
The data is encoded into the part of the URL after the #. Browsers never send that fragment to a server — not to ours, not to a CDN, and not in a Referer header — so the content travels inside the link itself. It is compressed first, which fits roughly 8 KB of JSON into a link short enough to survive email and chat clients.
It is private from us, and not private from whoever you send it to. Because the data is inside the link, anyone holding the link can read it — including anyone it gets forwarded to, and anything that logs URLs on their side. Treat a share link exactly as you would treat the file. We deliberately do not offer sharing on the JWT decoder, because a token is a credential.
Because it carries the data rather than storing it. Above about 8,000 characters, chat clients, email and some proxies start truncating URLs, which would produce a link that silently loads the wrong thing. Past that size, download the file and send that instead.