Developer tools · JSON formatter & validator
JavaScript object literals vs JSON: why single quotes fail validation
· How it works
json developer-workflow validation
An object printed by a JavaScript console looks like JSON but usually is not. This post lists the exact differences (quotes, unquoted keys, undefined, functions) and shows where each one trips a validator.
It came out of the console, so why is it invalid?
It came out of the console, so why is it invalid? — developer consoles display JavaScript values as JavaScript source-like text, not as a guaranteed JSON serialization. A copied object may contain bare property names, single-quoted strings, `undefined` or browser-specific annotations. All of those can be understandable to a JavaScript engine or human reader while failing immediately in a `.json` file, whose grammar is intentionally smaller and independent of executable code.
Consider `{name: "Ada", active: true, missing: undefined}`. The braces, colon and boolean resemble JSON, but the first bare key already violates the object-member rule, and `undefined` would fail later. ToolAcre reports the first unsupported character or value with a line and column, so conversion is best done in order.
Strings must use double quotes
Strings must use double quotes — JSON defines a string as characters enclosed by `"`, with backslash escapes where required. A single quote has no role as a string delimiter. When a validator meets `'Ada'`, it does not begin a string and then object to its contents; it rejects the opening apostrophe itself. This applies equally to property names and string values, even though JavaScript permits either quote style for its own literals.
Converting quotes requires more care than globally replacing every apostrophe. An apostrophe inside text such as `Ada's profile` is ordinary content once the value is double-quoted, while existing double quotes inside that content must be escaped. The valid JSON form is `"Ada's "profile""`.
Keys must be quoted strings
Keys must be quoted strings — JavaScript object literals allow identifier-style names such as `{name: 1}` and computed names such as `{[expression]: 1}`. JSON allows neither shorthand. After an opening brace or comma, the next member must begin with a double-quoted string, followed by a colon. The valid representation is `{"name": 1}`. A validator that points at the `n` is identifying the exact place where a quote was required.
Quoting every key also removes ambiguity around spaces, hyphens and reserved words. JavaScript may require different source syntax for those cases, but JSON uses one consistent rule: `"display-name"`, `"first name"` and `"default"` are all ordinary member names. Numeric-looking keys are strings too.
Values JSON simply does not have
Values JSON simply does not have — its value vocabulary is object, array, string, number, `true`, `false` and `null`. There is no `undefined`, `NaN`, `Infinity`, function, regular expression, BigInt or Date literal. Comments are absent from the grammar, and numbers cannot use hexadecimal, binary, leading plus signs or JavaScript numeric separators. Each borrowed construct eventually reaches a character that cannot begin or continue a valid JSON value.
Conversion requires a data decision rather than a spelling trick. Replace `undefined` with `null` only if an explicit empty value matches the application contract; otherwise remove the member or supply a real value. Encode dates as agreed strings, often ISO 8601. Represent non-finite numbers according to the receiving API instead of inventing a JSON token.
Worked example: converting a console dump into valid JSON
Worked example: converting a console dump into valid JSON — start with `{name: 'Ada', active: true, score: NaN, updated: new Date()}`. Quote `name`, `active`, `score` and `updated` with double quotes. Change the name value to a double-quoted string. Decide that an unavailable score should be `null`, and replace the constructor expression with the actual timestamp string it was meant to produce. The document now contains only JSON members and values.
The finished shape might be `{"name":"Ada","active":true,"score":null,"updated":"2026-03-21T10:00:00Z"}`. Validate after each category of repair because the first error can hide later JavaScript-only syntax. Formatting the accepted result then exposes its structure without performing any further conversion.
The reverse trap — valid JSON that JavaScript would read differently, such as very large integers and the __proto__ key
The reverse trap — valid JSON can still acquire JavaScript-specific behavior or limitations after parsing. JSON numbers have no built-in precision limit in the grammar, but JSON.parse produces JavaScript Number values. An integer beyond the safe range can therefore be rounded silently. If every digit matters, encode the identifier as a string or use a parser and data type designed to preserve arbitrary-precision numbers rather than trusting a successful syntax check.
The member name `"__proto__"` is also valid JSON and JSON.parse creates it as an own data property. Trouble can begin later if application code copies parsed properties into another object with unsafe assignment or merge behavior. Validation proves that the text follows JSON grammar; it does not prove that every key is safe for every consumer.
What this does not cover
What this does not cover — JSON5, JSONC and configuration languages that deliberately accept comments, trailing commas, unquoted names or single-quoted strings. Those formats solve different authoring problems and need parsers that implement their own grammars. A strict JSON validator should not silently reinterpret them, because accepting extra syntax would make its result misleading for APIs, package metadata and other destinations that genuinely require standard JSON.
This distinction also excludes arbitrary JavaScript evaluation. Running pasted text through `eval` or a Function constructor merely to turn an object literal into data can execute getters, calls or other hostile expressions. If the source is trusted JavaScript under your control, serialize the actual value with JSON.stringify. If the source is untrusted text, do not execute it.
Takeaway: a literal is code, JSON is data
Takeaway: a literal is code, JSON is data — visual similarity does not make their grammars interchangeable. JSON requires double-quoted strings and member names, permits only a small fixed set of value types and contains no comments or executable expressions. A line-and-column diagnostic marks the first place the copied source leaves that grammar. Repairing that point and validating again is more reliable than applying a broad search-and-replace to a console dump.
When you control the JavaScript value, generate JSON with JSON.stringify instead of copying its console representation. When you receive text, parse it only with the parser for its declared format and never execute it as a shortcut. Successful JSON validation establishes syntax, not numeric precision, schema conformance or safe downstream property handling.