JSON String Escape and Unescape Online
Escape text for a JSON string or unescape one back, per RFC 8259: quotes, backslashes, control characters, optional \uXXXX for non-ASCII. In your browser.
Worked examples
- Escape a multi-line message with quotes and a path
Quotes and backslashes get a backslash, and the newline and tab become \n and \t, so the value can sit inside a JSON string without breaking it.
- Escape non-ASCII text as \uXXXX
With ASCII-only output, é and ☕ become single \u escapes and the emoji (outside the Basic Multilingual Plane) becomes a surrogate pair, as RFC 8259 section 7 specifies.
- Unescape a JSON string literal
Pasting the value from a JSON file, with or without its surrounding quotes, restores the original text including the é and the surrogate-pair emoji.
What this tool does
This tool escapes text so it can sit safely inside a JSON string, and unescapes a JSON string back into plain text. It follows section 7 of RFC 8259, the JSON specification, and it runs entirely in your browser.
When you need it
- Putting a multi-line message, a file path or a snippet of code into a JSON payload by hand, for a
curlbody, a config file or a test fixture. - Reading a string copied out of a JSON log or API response that is full of
\n,\"andé. - Embedding JSON inside a string in another language, where you need the escaped form of a JSON string itself.
- Finding out why a hand-built JSON document is rejected as invalid.
What the RFC requires
Section 7 says a JSON string may contain any Unicode character except those that must be escaped: the quotation mark ", the reverse solidus \, and the control characters U+0000 through U+001F. That is the full list. Everything else, including the forward slash, accented letters and emoji, may appear as itself in a UTF-8 document.
The RFC provides short escapes for five of the controls (\b, \f, \n, \r, \t) and the six-character \uXXXX form for all others, so a bell character is \u0007. Hex digits can be either case; this tool writes lowercase, the same as Python's json.dumps. A character above U+FFFF, such as 😀, is written in \u form as a UTF-16 surrogate pair: 😀.
The options
Escape non-ASCII as \uXXXX rewrites every character outside printable ASCII (U+0020 to U+007E) as \u escapes. You only need this when the destination cannot be trusted with UTF-8, such as an ASCII-only log pipeline or a legacy system. Note that DEL (U+007F), which the RFC does not require escaping, is escaped in this mode, matching json.dumps(..., ensure_ascii=True). The output was compared with Python's json.dumps across a test set with quotes, backslashes, all control characters, DEL, U+2028, accented letters, CJK and emoji, and matched character for character, including after a round trip through json.loads.
Escape forward slash writes / as \/. The two forms mean the same thing, and the escape is optional. People use it when embedding JSON in an HTML script block so that </script> cannot end the block early. It is off by default so URLs stay readable.
Include surrounding quotes wraps the escaped value in double quotes, giving you a complete JSON string literal rather than just its content.
Unescaping, and why it can fail
Unescape mode accepts either the bare content or a full quoted literal, and reverses every legal escape. It is strict, as a real parser is, and tells you the position of the problem:
- an unescaped
"inside the text; - a raw newline, tab or other control character (JSON does not allow them unescaped);
- a backslash followed by anything other than
" \ / b f n r toruplus exactly four hex digits. Sequences such as\x41or\', which are valid in JavaScript or Python string literals, are not valid JSON.
If your text came from a source code literal rather than JSON, it may legitimately contain escapes JSON does not support. Unpaired surrogates, such as a lone \ud800, are legal JSON syntax and are decoded as they are.
Round trips
Escaping then unescaping returns your original text exactly, in all option combinations, because escaping is a one-to-one mapping and unescape accepts everything the escaper can write. The reverse is not guaranteed: unescape then escape can change text, since é and é are two spellings of the same character and \/ and / are two of the same slash.
Limits
Input is capped at 200,000 characters. Lengths shown are in UTF-16 code units, which is how JavaScript counts string length, so an emoji counts as 2.
Frequently asked questions
- Which characters must be escaped in a JSON string?
- RFC 8259 section 7 requires exactly three groups: the double quote, the backslash, and the control characters U+0000 through U+001F. Everything else, including the forward slash, emoji and any other Unicode, may appear as-is in a UTF-8 JSON document. The tool uses the short forms \n, \r, \t, \b and \f where they exist and \u00XX for the other control characters.
- Why would I escape non-ASCII characters?
- Only for transports that are not UTF-8 safe, such as embedding JSON in a Latin-1 or ASCII-only file or a log pipeline. The ASCII-only option writes anything outside printable ASCII as \uXXXX, using a surrogate pair (two escapes) for characters above U+FFFF such as emoji. This matches Python's json.dumps with its default ensure_ascii=True.
- Should the forward slash be escaped?
- It is optional: \/ and / mean the same thing in JSON. Escaping it is sometimes done so that the sequence </script> cannot end an inline script block when JSON is embedded in HTML. It is off by default and leaves ordinary URLs readable.
- Why does unescaping fail on my text?
- The unescape mode follows the grammar strictly. It rejects an unescaped double quote, a raw newline or other control character, a backslash followed by anything other than \" \\ \/ \b \f \n \r \t or \u and four hex digits (so \x41 and \' are errors, as in a real JSON parser), and it reports the position. Text that came from a JavaScript or Python string literal can contain escapes JSON does not allow.