You paste what looks like valid data into a JSON parser and it immediately throws SyntaxError: Unexpected token '''. The data came from your JavaScript source code and it looks completely reasonable — but JSON and JavaScript object literals are not the same format, and the differences matter more than most developers realise.
The Short Answer: JSON Does Not Support Single Quotes
Single quotes are flat-out illegal in JSON. Every string — both keys and values — must use double quotes. There are no exceptions.
// ❌ Invalid JSON — single-quoted strings
{ 'name': 'Ada Lovelace', 'active': true }
// ✅ Valid JSON
{ "name": "Ada Lovelace", "active": true }The error you'll see in different environments:
// Chrome / Node.js (V8)
SyntaxError: Unexpected token "'", "{'name':..." is not valid JSON
// Firefox
SyntaxError: JSON.parse: unexpected character at line 1 column 2 of the JSON data
// Safari
SyntaxError: JSON Parse error: Single quotes (') are not allowed in JSONSafari's error message is the most helpful — it tells you exactly what the problem is. The others just report the unexpected character.
Why Does JSON Require Double Quotes?
JSON was defined by Douglas Crockford in 2001 and standardised as RFC 8259 . The grammar specifies exactly one string delimiter: the double-quote character (U+0022). Single quotes are simply not in the grammar at all.
The reason is simplicity. JSON is a data interchange format meant to be parsed by any language, not just JavaScript. By mandating a single quoting style, the spec eliminates an entire class of ambiguity. Parsers in Go, Python, Java, Rust, and every other language all implement exactly the same rule.
JSON vs JavaScript Object Literal: the Full Differences
Single quotes are just one of several differences. Here's the complete picture:
1. Keys must be double-quoted strings
// ❌ JavaScript object literal — bare key, single-quoted key
{ name: "Ada", 'score': 98 }
// ✅ JSON — all keys are double-quoted strings
{ "name": "Ada", "score": 98 }JavaScript object literals accept bare identifiers, single-quoted strings, and double-quoted strings as keys. JSON accepts only double-quoted strings.
2. No trailing commas
// ❌ Invalid JSON
{ "name": "Ada", "score": 98, }
// ^ trailing comma
// ✅ Valid JSON
{ "name": "Ada", "score": 98 }Modern JavaScript explicitly allows trailing commas. JSON does not — see our full guide on trailing commas in JSON.
3. No comments
// ❌ Invalid JSON
{
// user profile
"name": "Ada"
}
// ✅ JSON has no comment syntax
{ "name": "Ada" }JSON has no comment syntax whatsoever. If you need comments in config files, consider the JSONC format (JSON-with-Comments), which is supported by VS Code settings, TypeScript's tsconfig.json, and several config-file parsers.
4. No undefined, functions, or symbols
// JavaScript object — accepts non-serialisable values
const obj = {
fn: () => 42, // function
sym: Symbol('id'), // Symbol
val: undefined, // undefined
};
// JSON.stringify silently drops or converts them
JSON.stringify(obj);
// → '{}' (all three properties are gone or become null) JSON supports exactly six value types: string, number, boolean (true/false), null, object, and array. Functions, Symbols, and undefined have no JSON representation. JSON.stringify() silently drops object properties with these values and converts them to null inside arrays.
5. No NaN or Infinity
JSON.stringify({ ratio: NaN, limit: Infinity });
// → '{"ratio":null,"limit":null}'
// NaN and Infinity become null — silently!
JSON.parse('{"ratio": NaN}');
// → SyntaxError: Unexpected token 'N'NaN and Infinity are valid JavaScript number values but are not part of the JSON number specification. JSON.stringify() converts them to null on the way out; JSON.parse() rejects them on the way in. This asymmetry is a common source of subtle bugs.
6. Numbers: no hex, no leading zeros, no +
// ❌ Invalid JSON
{ "flags": 0xFF, "code": 007, "delta": +1.5 }
// ✅ Valid JSON
{ "flags": 255, "code": 7, "delta": 1.5 } JSON numbers must be decimal, cannot start with an explicit + sign, and cannot have leading zeros (except for the single digit 0 before a decimal point). Hexadecimal literals and octal literals are not valid JSON.
7. No multi-line strings
// ❌ Invalid JSON — literal newline in string
{ "bio": "Line one
Line two" }
// ✅ Use the escape sequence
{ "bio": "Line one\nLine two" }8. Computed keys, Symbol keys, and method shorthand
Three more JS-only features that look like JSON but have no equivalent:
// ❌ Computed property names — evaluated, not literal
const k = "id";
const obj = { [k]: 1, [`user_${k}`]: 1 };
// JSON has no expressions; the key must be a literal double-quoted string.
// ❌ Symbol keys — silently dropped by JSON.stringify
const tag = Symbol('tag');
JSON.stringify({ [tag]: 'admin' }); // → '{}'
// ❌ Method shorthand — functions are dropped/omitted
const obj = { greet() { return 'hi'; } };
JSON.stringify(obj); // → '{}' If you need any of these, serialize a JSON-shaped projection of your object — JSON.stringify() only ever produces string keys and the six JSON value types.
A Quick Conversion Cheatsheet
| JavaScript object literal | Valid JSON equivalent |
|---|---|
{ name: "Ada" } | {"name":"Ada"} |
{ 'name': 'Ada' } | {"name":"Ada"} |
{ a: 1, } | {"a":1} |
{ val: undefined } | {} (property dropped) |
{ n: NaN } | {"n":null} |
{ n: Infinity } | {"n":null} |
{ fn: () => 1 } | {} (property dropped) |
0xFF | 255 |
The Safest Way to Convert a JS Object to JSON
Never try to convert a JavaScript object to JSON by manually editing quotes. Use JSON.stringify() — it handles every edge case correctly:
const obj = { name: 'Ada', score: 98, active: true };
// Compact
JSON.stringify(obj);
// → '{"name":"Ada","score":98,"active":true}'
// Pretty-printed with 2-space indent
JSON.stringify(obj, null, 2);
// → '{
"name": "Ada",
"score": 98,
"active": true
}' The second argument to JSON.stringify() is a replacer — you can pass an array of key names to include only those properties, or a function to transform values:
// Only include specific keys
JSON.stringify(obj, ['name', 'score'], 2);
// → '{
"name": "Ada",
"score": 98
}'
// Custom replacer — convert undefined to null
JSON.stringify({ a: 1, b: undefined }, (key, value) =>
value === undefined ? null : value
);
// → '{"a":1,"b":null}'When You Receive a JS Object Literal as a String
Sometimes you receive data that looks like JSON but is actually a JavaScript object literal — perhaps from a log file, a debugging tool, or an API that wasn't following the spec. In that case JSON.parse() will fail and you have two options:
- Use a repair parser — converts single quotes to double quotes, removes trailing commas, quotes bare keys, and handles all the other differences automatically. This is the safest approach for untrusted input.
- Use
eval()orFunction()— technically works for valid JavaScript, but is a serious security risk if the source is not fully trusted. Never do this with user-provided input.
Frequently Asked Questions
Does JSON support single quotes?
No. JSON's grammar (RFC 8259) defines exactly one string delimiter — the double quote. Both keys and values must use double quotes; single quotes throw a SyntaxError.
What's the difference between JSON and a JavaScript object?
JSON is a strict text format; a JavaScript object literal is permissive code. JS allows single quotes, unquoted keys, trailing commas, comments, undefined, NaN, functions, and hex numbers — none of which are valid JSON. See the full cheatsheet above and the primer at What Is JSON?
How do I convert a JavaScript object to JSON?
Use JSON.stringify() — never edit quotes by hand. It handles every edge case, dropping non-serialisable values and escaping strings correctly.
Why can't I use eval() to parse a JS object literal?
eval() executes arbitrary code, so it's a serious security risk on untrusted input. Use a repair parser (or JSON Fix) to convert a JS object literal to valid JSON safely instead.
Fix Single Quotes Instantly
If you have a JavaScript object literal that you need to convert to valid JSON right now, JSON Fix handles the conversion automatically. It converts single quotes to double quotes, quotes bare keys, removes trailing commas, and fixes all the other differences listed above — in your browser, with no data sent to any server.
- JSON Fix — convert JS object literals to valid JSON instantly
- Fix Single Quotes in JSON — quick reference guide with broken and fixed examples
- JSON vs JavaScript Object Literal — every syntax difference with side-by-side examples
- JSON.parse Unexpected Token errors — a guide to every variant of the SyntaxError you might see
- Trailing commas in JSON — why they're allowed in JS but forbidden in JSON