HomeBlog → JSON Escape & Unescape Guide

How to Escape and Unescape JSON Strings: Complete Guide (2026)

📅 Updated April 2026 ⏱ 10 min read 🛠 Practical guide

JSON string escaping is one of those topics that seems trivial until it breaks your API call at 2 AM. A raw double quote inside a string value, a stray newline copied from a text editor, or a Windows file path with backslashes — any of these can trigger a SyntaxError: Unexpected token and leave you puzzled. This guide explains every escape sequence in the JSON specification, shows you how to escape and unescape strings correctly in JavaScript, Python, Go, and PHP, and walks through the edge cases that trip up experienced developers.

Need to escape or unescape JSON right now?

Use the free online tool — paste your string and get the escaped or unescaped result instantly.

Open JSON Escape / Unescape Tool →

What is JSON String Escaping?

JSON (JavaScript Object Notation) encodes string values between a pair of double-quote characters. This creates an immediate problem: what do you do when the string itself contains a double quote? The answer is escaping — prefixing the problematic character with a backslash so the JSON parser knows it is part of the string value, not the end of the string.

Escaping is also necessary for several control characters. Bytes like newline (0x0A), tab (0x09), and carriage return (0x0D) are invisible characters that can silently corrupt a JSON document when pasted from a text editor or copied from a database field. The JSON specification (RFC 8259) requires that all characters in the range U+0000 to U+001F be escaped using either a short escape sequence or a \uXXXX Unicode escape.

You encounter escaping whenever you:

Unescaping is the reverse operation: taking an escaped JSON string representation and converting the escape sequences back to their literal characters, producing the original text.

Complete Escape Sequence Reference

The JSON specification defines exactly nine escape sequences. Every conformant JSON parser must support all nine, and every JSON serializer must use them when required:

Escape Sequence Character Unicode Code Point When Required
\"Double quoteU+0022Inside any JSON string
\\Backslash (reverse solidus)U+005CInside any JSON string
\/Forward slash (solidus)U+002FOptional — allowed but not required
\nLine feed (newline)U+000ARequired — raw newline is forbidden
\rCarriage returnU+000DRequired — raw CR is forbidden
\tHorizontal tabU+0009Required — raw tab is forbidden
\bBackspaceU+0008Required — raw backspace is forbidden
\fForm feedU+000CRequired — raw form feed is forbidden
\uXXXXUnicode code pointAnyRequired for U+0000–U+001F; optional for others

A few critical notes on this table: the backslash (\\) and double quote (\") are the only two characters that must always be escaped inside a JSON string. The control characters (\n, \r, \t, \b, \f) must be escaped because their raw byte values are forbidden inside JSON string literals. Forward slash is the only optional escape — the spec permits \/ but does not require it, and most parsers handle / without escaping just fine.

Examples of Each Escape Sequence

{
  "double_quote":   "He said \"hello\" to her.",
  "backslash":      "C:\\Users\\alice\\documents",
  "forward_slash":  "https://jsonwebtools.com\/api",
  "newline":        "Line one.\nLine two.",
  "carriage_return":"Windows line ending:\r\n",
  "tab":            "Column1\tColumn2\tColumn3",
  "backspace":      "Erase last char:\b",
  "form_feed":      "Page break here:\f",
  "unicode":        "Copyright symbol: \u00A9",
  "emoji_via_unicode": "Snowman: \u2603"
}

The Most Common Escaping Mistakes

Despite the spec being clear, the same three errors account for the vast majority of JSON string SyntaxError exceptions in production code:

1. Raw Newlines Inside Strings

This is by far the most common mistake. When you copy text from a text editor, a database VARCHAR field, or a user-submitted form, the string may contain literal newline characters. Pasting that text into a JSON string without escaping it produces invalid JSON:

❌ Invalid — raw newline inside the string literal

{
  "message": "Hello,
World"
}

✅ Valid — newline properly escaped as \n

{
  "message": "Hello,\nWorld"
}

2. Unescaped Double Quotes

Building JSON by hand with string concatenation frequently leads to unescaped quotes. If a user's name contains a double quote — say, their nickname is written as nickname "The Rock" — naive concatenation breaks the JSON structure entirely:

❌ Invalid — the inner double quotes terminate the string prematurely

// Naive string concatenation (NEVER do this)
const name = 'Alice "The Boss" Johnson';
const json = '{"name": "' + name + '"}';
// Produces: {"name": "Alice "The Boss" Johnson"} — INVALID

✅ Valid — use JSON.stringify() instead

const name = 'Alice "The Boss" Johnson';
const json = JSON.stringify({ name });
// Produces: {"name":"Alice \"The Boss\" Johnson"} — VALID

3. Backslash in Windows File Paths

Windows file paths use backslash as the directory separator. A single backslash in a JSON string must be doubled to \\:

❌ Invalid — single backslashes are not valid JSON escape sequences

{ "path": "C:\Users\alice\report.txt" }

✅ Valid — backslashes doubled

{ "path": "C:\\Users\\alice\\report.txt" }

How to Escape JSON Strings in JavaScript

JavaScript has built-in JSON support through the global JSON object. You should almost always use it rather than writing your own escaping logic.

Using JSON.stringify()

JSON.stringify() converts any JavaScript value to a JSON string, handling all escaping automatically:

// Escaping a plain string value
const raw = 'He said "hello"\nNew line here\tTabbed';
const escaped = JSON.stringify(raw);
// Result: '"He said \\"hello\\"\\nNew line here\\tTabbed"'
// (The outer quotes are part of the JSON string representation)

// Escaping an object (most common use case)
const obj = {
  message: 'Line 1\nLine 2',
  path: 'C:\\Windows\\System32',
  quote: 'She said "goodbye"'
};
console.log(JSON.stringify(obj));
// {"message":"Line 1\nLine 2","path":"C:\\Windows\\System32","quote":"She said \"goodbye\""}

JSON.stringify() accepts two optional extra parameters: a replacer (array of keys or a function to filter/transform values) and a space (number of spaces or a string for pretty-printing):

// Pretty-print with 2-space indent
console.log(JSON.stringify(obj, null, 2));

// Only include specific keys
console.log(JSON.stringify(obj, ['message', 'path']));

Template Literals Pitfalls

A common mistake is using template literals to construct JSON. Template literals do not escape JSON — they just perform string interpolation:

❌ Dangerous — template literal does not escape special characters

const userInput = 'He said "run"';
const badJson = `{"msg": "${userInput}"}`;
// Produces: {"msg": "He said "run""} — INVALID JSON

✅ Safe — always use JSON.stringify

const userInput = 'He said "run"';
const goodJson = JSON.stringify({ msg: userInput });
// Produces: {"msg":"He said \"run\""} — VALID JSON

How to Unescape JSON in JavaScript

Unescaping a JSON string means parsing the JSON representation back into a JavaScript value. The correct tool is JSON.parse():

// Unescaping a JSON string
const jsonString = '"He said \\"hello\\"\\nNew line here"';
const original = JSON.parse(jsonString);
console.log(original);
// He said "hello"
// New line here

// Unescaping a full JSON object
const jsonObj = '{"path":"C:\\\\Users\\\\alice","msg":"Line 1\\nLine 2"}';
const parsed = JSON.parse(jsonObj);
console.log(parsed.path);  // C:\Users\alice
console.log(parsed.msg);   // Line 1
                            // Line 2

Why Manual Regex Unescaping is Risky

You might be tempted to unescape with a regex replace. This approach fails on edge cases like \\n (a literal backslash followed by n, not a newline), Unicode surrogates, and the order of replacements. Always prefer JSON.parse() in a try/catch:

function safeJsonParse(str) {
  try {
    return { value: JSON.parse(str), error: null };
  } catch (e) {
    return { value: null, error: e.message };
  }
}

Escaping in Python

Python's json module is part of the standard library and handles escaping and unescaping transparently.

json.dumps() — Escaping

import json

# Escaping a Python dict to a JSON string
data = {
    "message": "Hello,\nWorld",
    "path": "C:\\Users\\alice",
    "quote": 'She said "goodbye"'
}
json_string = json.dumps(data)
print(json_string)
# {"message": "Hello,\nWorld", "path": "C:\\Users\\alice", "quote": "She said \"goodbye\""}

json.loads() — Unescaping

import json

json_string = '{"message": "Hello,\\nWorld", "quote": "She said \\"hi\\""}'
data = json.loads(json_string)
print(data["message"])  # Hello,
                        # World
print(data["quote"])    # She said "hi"

Handling Unicode in Python

By default, json.dumps() escapes non-ASCII characters as \uXXXX sequences. If you want to preserve UTF-8 characters literally (e.g., for readability), use ensure_ascii=False:

import json

data = {"greeting": "こんにちは", "flag": "🇯🇵"}

# Default: non-ASCII characters are escaped
print(json.dumps(data))
# {"greeting": "\u3053\u3093\u306b\u3061\u306f", "flag": "\ud83c\uddef\ud83c\uddf5"}

# With ensure_ascii=False: characters are preserved as-is
print(json.dumps(data, ensure_ascii=False))
# {"greeting": "こんにちは", "flag": "🇯🇵"}

Escaping in Go

Go's encoding/json package handles escaping automatically when you marshal values. You rarely need to escape strings manually in Go.

package main

import (
    "encoding/json"
    "fmt"
)

type Message struct {
    Text string `json:"text"`
    Path string `json:"path"`
}

func main() {
    msg := Message{
        Text: "Hello,\nWorld — she said \"hi\"",
        Path: `C:\Users\alice\docs`,
    }

    // Marshal automatically escapes special characters
    data, err := json.Marshal(msg)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Println(string(data))
    // {"text":"Hello,\nWorld \u2014 she said \"hi\"","path":"C:\\Users\\alice\\docs"}

    // Unmarshal — unescaping is automatic
    var decoded Message
    json.Unmarshal(data, &decoded)
    fmt.Println(decoded.Text) // Hello,
                               // World — she said "hi"
}

Note that Go's encoding/json escapes certain characters like &, <, and > as Unicode sequences (\u0026, \u003c, \u003e) for HTML safety by default. To disable this behavior, use a json.Encoder with SetEscapeHTML(false):

var buf bytes.Buffer
enc := json.NewEncoder(&buf)
enc.SetEscapeHTML(false)
enc.Encode(msg)

Escaping in PHP

PHP's json_encode() function handles escaping by default. Several flags let you control the escaping behavior:

<?php
$data = [
    "message" => "Hello,\nWorld",
    "path"    => "C:\\Users\\alice",
    "url"     => "https://example.com/api",
    "greeting"=> "こんにちは"
];

// Default: escapes Unicode and forward slashes
echo json_encode($data);
// {"message":"Hello,\nWorld","path":"C:\\Users\\alice","url":"https:\/\/example.com\/api","greeting":"\u3053\u3093\u306b\u3061\u306f"}

// JSON_UNESCAPED_UNICODE: preserve multi-byte characters
echo json_encode($data, JSON_UNESCAPED_UNICODE);
// {"message":"Hello,\nWorld","path":"C:\\Users\\alice","url":"https:\/\/example.com\/api","greeting":"こんにちは"}

// JSON_UNESCAPED_SLASHES: don't escape forward slashes
echo json_encode($data, JSON_UNESCAPED_SLASHES);
// {"message":"Hello,\nWorld","path":"C:\\Users\\alice","url":"https://example.com/api","greeting":"\u3053\u3093..."}

// Combine flags with bitwise OR
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);

To unescape, use json_decode():

<?php
$jsonString = '{"message":"Hello,\nWorld","quote":"She said \"hi\""}';
$data = json_decode($jsonString, true); // true = associative array
echo $data['message']; // Hello,
                       // World
echo $data['quote'];   // She said "hi"

Escaping JSON for HTML Embedding

When you embed JSON inside an HTML <script> tag, you face a second layer of escaping requirements. Even valid JSON can break an HTML page or create a cross-site scripting (XSS) vulnerability if the JSON contains characters that have special meaning in HTML.

The primary risks are:

<!-- DANGEROUS: if JSON contains </script>, the page breaks -->
<script>
  const data = <?php echo json_encode($data); ?>;
</script>

<!-- SAFE: escape characters that end script blocks -->
<script>
  const data = <?php echo str_replace(
    ['</', '<!', '-->'],
    ['\u003c/', '\u003c!', '--\u003e'],
    json_encode($data)
  ); ?>;
</script>

In JavaScript server-side frameworks, libraries like serialize-javascript or framework-level utilities (Next.js's JSON.stringify with HTML-safe option) handle this automatically. Always prefer a library over hand-rolling the HTML-safety layer.

Unicode Escaping

The \uXXXX escape sequence represents any Unicode code point using four hex digits. It is required for control characters (U+0000–U+001F) and optional for all other code points. Any character above U+007F can optionally be written as a \u escape instead of its UTF-8 representation.

When to Use \uXXXX

Emoji and High Unicode Code Points

Emoji and other characters above U+FFFF cannot be expressed in a single \uXXXX sequence. They require a surrogate pair of two \uXXXX sequences. For example, the smiling face emoji 😀 (U+1F600) is encoded as the surrogate pair \uD83D\uDE00:

// JavaScript
JSON.stringify({ emoji: "😀" })
// '{"emoji":"😀"}'   ← most parsers keep the raw UTF-8

// If you need ASCII-only output, you must encode surrogates manually:
// \uD83D\uDE00  ← represents U+1F600 (😀)

// Python with ensure_ascii=True (default)
import json
json.dumps({"emoji": "😀"})
# '{"emoji": "\\ud83d\\ude00"}'

Most modern JSON parsers handle both raw UTF-8 emoji and surrogate pair encodings correctly. The safest approach for maximum compatibility is to use your language's standard JSON library and let it decide when to use \uXXXX versus raw UTF-8.

Frequently Asked Questions

What characters need to be escaped in JSON strings? +
JSON requires escaping these characters inside strings: double quote (\"), backslash (\\), and all control characters in the range U+0000–U+001F including newline (\n), carriage return (\r), tab (\t), backspace (\b), and form feed (\f). Forward slash (\/) may optionally be escaped. Any Unicode code point can be escaped as \uXXXX.
How do I escape a JSON string in JavaScript? +
Use JSON.stringify(). For a plain string: JSON.stringify(myString) returns the JSON-encoded version including outer quotes. For embedding in an object: JSON.stringify({ key: myString }). Never build JSON by hand with string concatenation — always use JSON.stringify() to avoid injection bugs and missed edge cases.
Why does my JSON have a SyntaxError on a string? +
The most common causes are: (1) a raw newline or carriage return inside a string value — replace with \n or \r; (2) an unescaped double quote inside a string — replace with \"; (3) a raw backslash — replace with \\. Use the JSON Escape/Unescape tool to fix these automatically, or the JSON Repair tool to auto-fix common mistakes.
What is the difference between JSON.stringify and JSON.parse for escaping? +
JSON.stringify() converts a JavaScript value into a JSON string, adding all necessary escape sequences. JSON.parse() does the reverse — it takes a JSON string and converts it back to a JavaScript value, interpreting all escape sequences. Use stringify to escape, parse to unescape.
Is it safe to escape JSON strings with a regex? +
Generally no. Manual regex-based escaping is error-prone — easy to miss control characters below U+001F, double-escape existing backslashes, or mishandle Unicode surrogates. Always use your language's built-in JSON library: JSON.stringify in JavaScript, json.dumps in Python, encoding/json in Go, json_encode in PHP.

Related Tools & Guides

JSON Escape / Unescape Tool  |  JSON Formatter  |  JSON Validator  |  JSON Repair Tool  |  JSON SyntaxError Guide