← All articles

Single Quotes in JSON: Why JavaScript Objects Parse and JSON.parse Fails

Single quotes are valid in JavaScript object literals, not JSON. Compare the exact syntax differences, conversion traps, JSON.stringify behavior, safe repair workflows, and when not to use eval.

You paste this into JSON.parse():

JSON.parse("{ 'name': 'Ada Lovelace', 'active': true }");

and JavaScript throws an error near the first quote. The text looks like data, and it even looks familiar if you write JavaScript every day. But it is not JSON. It is a JavaScript-style object literal written as text.

The short rule is simple: JSON strings and JSON object keys must use double quotes. Single quotes are never valid JSON string delimiters. The practical rule is a little more useful: do not fix single-quoted JSON with blind find-and-replace, and do not parse JavaScript-looking text with eval() unless you fully control the source.

Quick Answer

Question Answer
Does JSON allow single quotes? No. JSON strings and object keys use double quotes only.
Does JavaScript allow single quotes? Yes, inside JavaScript source code. That does not make the text valid JSON.
Can JSON.stringify() output single-quoted JSON? No. It always emits valid JSON strings with double quotes.
Can JSON.parse() read JavaScript object literals? No. It reads JSON text, not JavaScript code.
Is { name: 'Ada' } valid JavaScript? Yes, as source code.
Is { name: 'Ada' } valid JSON? No. The key is unquoted and the string uses single quotes.
Is eval() a safe converter? No for untrusted input. It executes code.
What is the safest fix? Use JSON.stringify() when you already have a JS value; use a repair parser for pasted literal text.

Valid JavaScript, Invalid JSON

This object literal is valid JavaScript source:

const user = {
  name: 'Ada Lovelace',
  active: true,
  roles: ['admin', 'editor'],
};

This is valid JSON text:

{
  "name": "Ada Lovelace",
  "active": true,
  "roles": ["admin", "editor"]
}

The JSON version has three important differences:

  • object keys are double-quoted strings
  • string values use double quotes
  • the trailing comma after the last array item or object member is gone

That is the shape an API, webhook, config loader, database import, or JSON.parse() call expects.

Why JSON Requires Double Quotes

JSON is a data interchange format, not a JavaScript subset with every JavaScript convenience left in. Its grammar defines strings with the double quote character. Single quote is not an alternate delimiter.

That strictness is the point. A Go service, a Python script, a Java backend, a Rust CLI, a database import tool, and a browser can all agree on the same syntax without executing JavaScript.

When parsers reject single quotes, they are not being picky. They are enforcing the contract that makes JSON portable across languages.

Typical errors:

SyntaxError: Unexpected token "'", "{'name':..." is not valid JSON
SyntaxError: JSON.parse: unexpected character at line 1 column 2 of the JSON data
SyntaxError: JSON Parse error: Single quotes (') are not allowed in JSON
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes
parse error: Expected string at line 1, column 2

The exact message changes by parser. The fix is the same: produce strict JSON, or repair the JavaScript-like input before parsing it as JSON.

JSON vs JavaScript Object Literal

Single quotes are only one difference. This is the comparison that matters when a payload "looks like JSON" but keeps failing.

Feature JavaScript object literal Strict JSON
String delimiters single quotes, double quotes, template literals in code double quotes only
Object keys bare identifiers, quoted strings, computed keys double-quoted strings only
Trailing commas allowed not allowed
Comments allowed in JS source not allowed
undefined valid JavaScript value not representable
Functions and methods valid in objects not representable
NaN and Infinity valid JavaScript numbers not valid JSON numbers
Date, RegExp, Map, Set JavaScript objects need explicit JSON-shaped encoding
Hex and binary numbers 0xff, 0b1010 are valid JS decimal JSON numbers only
Numeric separators 1_000 is valid JS invalid JSON
Computed keys { [key]: value } no expressions

If you need the broader comparison, the companion guide JSON vs JavaScript Object Literal covers every syntax difference side by side.

Do Not Fix Single Quotes With Search and Replace

This is the common mistake:

const input = "{ 'note': 'it\\'s ready', 'quote': 'She said \"yes\"' }";
const wrong = input.replace(/'/g, '"');

The replacement cannot tell the difference between:

  • a single quote that opens a string
  • a single quote that closes a string
  • an escaped apostrophe inside a string value
  • a single quote inside normal text

After the replacement, the example can become syntactically broken or subtly changed. It is even worse when values contain contractions, possessives, SQL snippets, shell commands, or natural-language text.

A safe converter must tokenize the input: detect string boundaries, convert delimiters, preserve apostrophes inside values, escape interior double quotes, and then validate the result as strict JSON.

If You Already Have a JavaScript Value, Use JSON.stringify

When the data is already a JavaScript object in memory, do not convert it by editing source text. Serialize the value:

const user = {
  name: 'Ada Lovelace',
  active: true,
  roles: ['admin', 'editor']
};

const json = JSON.stringify(user, null, 2);
console.log(json);

Output:

{
  "name": "Ada Lovelace",
  "active": true,
  "roles": [
    "admin",
    "editor"
  ]
}

JSON.stringify() is the right tool because it escapes strings correctly and emits strict JSON. But it is not magic. It only serializes values JSON can represent.

Watch the lossy cases:

JavaScript value JSON.stringify result
object property with undefined property omitted
array item with undefined null
function property property omitted
symbol-keyed property omitted
NaN, Infinity, -Infinity null
Date ISO string
BigInt throws TypeError
circular reference throws TypeError

If those conversions are not acceptable, create a JSON-shaped payload deliberately before calling JSON.stringify().

const payload = {
  name: user.name,
  active: Boolean(user.active),
  createdAt: user.createdAt.toISOString(),
  roles: user.roles.map(String)
};

const json = JSON.stringify(payload);

If You Have JavaScript-Looking Text, Treat It as Untrusted

Sometimes the input is not a live JavaScript value. It is a string copied from somewhere:

  • a browser console
  • a log line
  • an LLM response
  • an old config file
  • a bug report
  • a Python print(dict) output
  • a Ruby or JavaScript inspection string

That text is not automatically safe to execute. It may contain code, getters, function calls, imports, prototype tricks, or just syntax your runtime will execute if you run it as JavaScript.

Do this for pasted or untrusted text:

  1. Repair it with a parser that understands JavaScript-like literal mistakes.
  2. Review the repaired JSON.
  3. Validate the result as strict JSON.
  4. Apply schema or business validation if the data affects anything important.

Use JSON Fix for browser-local repair, or the focused guide Fix Single Quotes in JSON if the only issue is quote style.

Why eval and Function Are the Wrong Shortcut

This works only because it executes JavaScript:

const text = "({ name: 'Ada', active: true })";
const value = Function(`return ${text}`)();

It is not a JSON parser. It is code execution. If text comes from a user, a log, an email, a webhook, a file upload, or an LLM, this is a security bug waiting for a payload.

Even when the source is trusted, JavaScript evaluation accepts things you may not want in data:

({
  now: new Date(),
  run: (() => process.env.SECRET)(),
  get role() {
    return 'admin';
  }
})

Strict JSON parsers reject all of that. That rejection is a feature, not a limitation.

Language-Specific Literal Output Is Not JSON

Single quotes often come from a language printing its own literal format.

Python example:

data = {'name': 'Ada', 'active': True, 'missing': None}
print(data)

Output:

{'name': 'Ada', 'active': True, 'missing': None}

That is Python repr-style output, not JSON. Strict JSON would be:

{"name":"Ada","active":true,"missing":null}

In Python, the right producer-side fix is:

import json

print(json.dumps(data))

If you truly need to parse a trusted Python literal, ast.literal_eval is safer than eval, but it still parses Python syntax, not JSON. For API payloads and cross-language files, make the producer emit JSON instead.

JSON5 and JSONC Are Different Contracts

Some config formats intentionally allow JavaScript-like conveniences:

  • JSON5 allows single quotes, comments, trailing commas, and more.
  • JSONC allows comments and trailing commas in tools such as VS Code settings and tsconfig.json.

Those are useful for human-edited config. They are not the same as strict RFC 8259 JSON. Do not send JSON5 or JSONC as an API request body unless the server explicitly says it accepts that media type or parser behavior.

For public APIs, webhooks, database imports, and cross-language data exchange, use strict JSON.

Conversion Cheat Sheet

Input you have What to do
A JavaScript object value JSON.stringify(value, null, 2)
A JSON string with single quotes Repair it, then validate strict JSON
A JavaScript object literal copied from code Prefer running the original value through JSON.stringify() in a trusted environment
A browser console object display Copy as JSON if DevTools supports it, or serialize the real value
Python print(dict) output Fix the Python producer with json.dumps()
LLM "JSON" with single quotes Repair, validate, then schema-check required fields
JSON5 or JSONC config Parse with a JSON5/JSONC parser, or convert to strict JSON for interchange
API request body Send strict JSON only

A Practical Debugging Workflow

When you see a single-quote parse error:

  1. Look at the first failing character and confirm whether it is a quote, bare key, comment, or trailing comma.
  2. Identify the source: JS object value, JS literal text, Python repr, JSON5, JSONC, or malformed API payload.
  3. If you own the producer, fix the producer to emit JSON with JSON.stringify(), json.dumps(), or the equivalent serializer.
  4. If the input is pasted or temporary, repair it and validate the output.
  5. If the input is untrusted, do not use eval(), Function(), or regex quote replacement.
  6. After conversion, compare the parsed value against the expected schema.

That last step matters because quote repair only fixes syntax. It cannot tell whether "role": "admin" is allowed, whether null is acceptable, or whether a required field is missing.

Frequently Asked Questions

Does JSON support single quotes?

No. JSON strings and object keys must use double quotes. Single quotes are valid in JavaScript source code, Python literals, and JSON5, but not in strict JSON.

Why does JSON.parse reject single quotes?

JSON.parse() implements the JSON grammar, not the JavaScript object-literal grammar. A single quote cannot start a JSON string, so the parser reports an unexpected character.

What is the difference between JSON and a JavaScript object literal?

JSON is strict data text. A JavaScript object literal is source code. JavaScript can use single quotes, bare keys, comments, trailing commas, undefined, functions, NaN, and computed keys; strict JSON cannot.

How do I convert a JavaScript object to JSON?

Use JSON.stringify(value), or JSON.stringify(value, null, 2) for readable output. If the object contains undefined, functions, symbols, BigInt, dates, or circular references, decide how those should be represented first.

Can I replace all single quotes with double quotes?

Not safely. Blind replacement can corrupt apostrophes and escaped quotes inside string values. Use a repair parser that understands string boundaries, then validate the result.

Why should I not use eval to parse a JavaScript object literal?

eval() and Function() execute code. That is dangerous for untrusted input and also accepts JavaScript features that are not data. Use a repair parser or fix the producer to emit JSON.

Are JSON5 and JSONC valid JSON?

No. They are useful JSON-like formats for human-edited config, but they are not strict JSON. Convert them before sending data across an API or language boundary.

How do I fix Python dict output with single quotes?

Change the producer to use json.dumps(data) instead of print(data) or str(data). Python's printed dict syntax uses single quotes, True, False, and None, which are not JSON.

Fix Single Quotes Safely

If you need to clean a pasted sample, use JSON Fix. It repairs single quotes, quotes bare keys, removes trailing commas, handles common Python/JavaScript literals, and formats the final JSON in your browser without uploading the payload.

Related guides:

Sources

Last reviewed July 2026.