Tools
Guides

JSON String Escape / Unescape

JSON

Escape and unescape JSON strings — quotes, control characters and \uXXXX.

100% client-side No backend
Input
Output
On this page

What is JSON string escaping?#

Inside a JSON document, a string has to sit between double quotes — and that creates a problem the moment the text itself contains a quote, a newline, or a backslash. If you just dropped them in raw, the parser would see the closing quote too early, or treat \ as the start of an escape it does not understand. Escaping is the act of replacing those characters with the short backslash sequences the JSON spec defines: \" for a quote, \\ for a backslash, \n for a newline, \t for a tab, and a few more. Unescaping is the reverse — turning those sequences back into the original characters.

There is a second, harsher mode. Some legacy systems — older log shippers, restrictive databases, transit layers that assume pure ASCII — choke on any byte above 127. For those, JSON also lets you write any non-ASCII character as \uXXXX (and astral characters like emoji as a UTF-16 surrogate pair). The text is still valid JSON; it just happens to be made entirely of ASCII after escaping.

This page does both directions and both modes: escape a raw string into a valid JSON string literal, or unescape a literal back to its original text — with an optional ASCII-only switch that forces every non-ASCII code point into \uXXXX form.

How to use it#

  1. Pick the direction with the Encode / Decode toggle at the top-left of the toolbar. Encode escapes raw text into a JSON literal; Decode unescapes a literal back to text.
  2. Type or paste into the Input pane on the left.
    • In Encode, the whole text becomes one JSON string literal (surrounding quotes included).
    • In Decode, you can paste either a quoted literal ("a\nb") or just the bare escaped body (a\nb) — the tool wraps it in quotes for you. A valid JSON number, boolean, or object is rejected as “not a string” rather than silently coerced.
  3. Tick ASCII-only output (\uXXXX) (Encode mode) when the downstream consumer cannot handle non-ASCII bytes. Astral characters like emoji are emitted as a proper surrogate pair, exactly as JSON.stringify would.
  4. The result appears live in the Output pane. Click Copy to grab it.
  5. Sample drops in a multi-language demonstration string; Clear resets both panes.

Key features#

  • Spec-exact short forms. Uses precisely the sequences required by RFC 8259 (\", \\, \b, \f, \n, \r, \t) and \uXXXX for everything else below 0x20 — matching JSON.stringify byte-for-byte.
  • Real ASCII-only mode. Non-ASCII characters are not silently dropped or mojibake’d; each is emitted as \uXXXX, and astral characters (above U+FFFF) become a correct UTF-16 surrogate pair, not a broken lone code unit that decoders will reject.
  • Tolerant unescape. Accepts both a fully quoted literal and a bare escaped body, so half-pasted fragments from a log line still decode instead of throwing.
  • Refuses to guess. If the decoded input is valid JSON but not a string (for example a bare number or an array), the tool tells you so instead of stringifying it behind your back.

Worked example#

Load Sample in Encode mode and the input is a string deliberately mixing quotes, a backslash path, a newline, a copyright sign, an emoji, and Chinese:

He said "hi"
\path\ © 🌍 你好

Without ASCII-only, the escaped literal keeps the readable characters verbatim and only quotes what must be quoted:

"He said \"hi\"\n\\path\\ © 🌍 你好"

Now tick ASCII-only output (\uXXXX) and the same input becomes pure ASCII — the copyright sign collapses to the four-character form \u00a9, the globe emoji to the surrogate pair \ud83c\udf0d, and each Chinese character to its own code point (\u4f60, \u597d):

"He said \"hi\"\n\\path\\ \u00a9 \ud83c\udf0d \u4f60\u597d"

Switch to Decode and paste either of those literals back: the original text — including the emoji and the Chinese — is restored exactly.

FAQ#

Why does the emoji turn into two \u codes instead of one?#

Characters above U+FFFF (emoji, rare CJK extensions, some mathematical symbols) do not fit in a single 16-bit code unit, so UTF-16 represents them as a surrogate pair — a high surrogate followed by a low surrogate. The globe emoji 🌍 (U+1F30D) becomes \ud83c\udf0d. Emitting only one \u would produce invalid JSON that strict decoders reject; this tool emits the pair exactly as JSON.stringify does, so the output round-trips.

Decode says “Input is not a JSON string.” What did I paste?#

You pasted something that is valid JSON but not a string — typically a bare number (42), a boolean (true), or an object/array. The tool refuses to stringify it because that would hide a real mistake (you almost certainly meant to paste the string value, not the whole document). Wrap your text in quotes and try again.

Does this handle control characters like a literal tab or bell?#

Yes. A literal tab in the input becomes \t, a backspace \b, a form feed \f, a carriage return \r; any other control code below U+0020 (including the bell, 0x07) becomes a \u0007-style code. That matters because raw control characters are illegal inside JSON strings and some parsers reject them outright.

Is ASCII-only output “safer”?#

Only for a specific kind of safety: surviving a transit layer that mangles or rejects non-ASCII bytes. It is not a security measure — the data is still plainly reversible, just expressed in a more restrictive alphabet. Use it when a consumer demands ASCII; leave it off otherwise, since the readable form is far easier to debug.