creatorvalet Search

JSON escape and unescape

Spell a string so it can sit between quotes in JSON, or read that spelling back. It says what your line endings did on the way in — because a textarea changes them and does not tell you.

  • SECURE
  • NO UPLOADS
  • NO SIGNUP
  • BROWSER BASED
  • FREE
  • FOREVER.

Support us with a link or a share

Waiting
Characters in
Sequences written
Characters out
No. 2716waiting

Nothing at the counter yet.

A textarea rewrites CRLF to LF. The HTML specification requires it, before any script can look, so pasted text arrives with 0 CRLF pairs and 0 lone LF no matter what you copied. If your line endings are the point, open the file instead.

JSON accepts café and 🎉 exactly as they are. Turn this on when the receiver is an old parser or a log that mangles UTF-8. An emoji becomes a surrogate pair — two sequences meaning one character.

Never required, and needed in exactly one place: JSON inside a <script> tag, where the text </script> inside a string would close the tag early.

What JSON requires, and what it merely allows

CharacterJSON writes itWhy
\\\A backslash starts every other escape, so it has to escape itself first.
"\"A double quote would end the string early.
LF\nLine feed. JSON forbids a raw control character inside a string.
CR\rCarriage return. Half of a Windows line ending, and the half that gets lost.
Tab\tTab. Forbidden raw, and invisible when it survives.
Backspace\bBackspace, U+0008.
Form feed\fForm feed, U+000C.
/\/Optional. Only needed when the JSON sits inside a <script> tag, where the text </script> would close it.
anything else\uXXXXEvery control character below U+0020 must be written this way — JSON forbids a raw one inside a string. Characters above ASCII may be, and only are when you ask.

Nothing you type or open here is uploaded, put in the URL, or written to a log. The escaping runs in this tab.

What a JSON escape actually does

A JSON string is text between two double quotes, and that arrangement immediately creates a problem: the moment your text contains a double quote of its own, the string ends early and the rest of your data becomes syntax. Escaping is the fix. A backslash in front of a character tells the parser to treat it as content rather than as punctuation, and JSON defines a small, closed set of these spellings — seven short ones and one numeric one — which is the entire vocabulary you are working with.

Two of the seven are obvious. The double quote has to be escaped because it would close the string, and the backslash has to be escaped because it introduces every other escape, so a literal backslash needs one of its own in front of it. The other five are control characters with names: line feed, carriage return, tab, backspace and form feed. These are not merely convenient abbreviations. RFC 8259 forbids every raw control character below U+0020 from appearing inside a string, so a tab that survives unescaped does not produce ugly JSON — it produces JSON that no conforming parser will accept. That is why anything else below U+0020, a null byte for instance, has to be written in the numeric form \u0000.

Everything above that is optional, and knowing which parts are optional is most of what separates a considered escape from a superstitious one. An accented letter is legal exactly as it is. So is an emoji. So, for that matter, is the forward slash — you will see \/ constantly in JSON produced by older libraries, and nothing in the specification asks for it. This page therefore leaves those alone by default and makes each one a visible choice with the reason written next to it, rather than escaping everything and calling the result safe.

The line-ending trap, which is the hard part of this page

Here is a failure that this tool cannot fix and can only be honest about. The HTML specification requires a <textarea> to normalize its raw value, which means every carriage-return-and-line-feed pair becomes a single line feed before any script is allowed to see the field. It happens on paste, on typing, and on drop. No JavaScript can read what was there a moment earlier, and no clever workaround exists, because by the time your code runs the carriage returns are already gone.

For most tools that hardly matters. For this one it is central, because the single most common reason to escape a string carefully is that its line endings matter — a Windows file being embedded in a payload, a certificate, a multi-line configuration value that a Unix parser will read later. If you paste that text here you will get an answer about LF, not about CRLF, and it will look completely correct. So the page says so out loud next to the field, counts the CRLF pairs and lone line feeds it can actually see, and offers the file picker as the path that preserves them. Opening a file reads its bytes directly, and the counter then reports what the file genuinely contains, so you can verify the claim instead of believing it.

Escaping a string that was already escaped

The second trap is quieter. Suppose your text literally contains a backslash followed by the letter n — two characters, not a line break — because it has already been through an escaper once, or because it came out of a log where a value was serialized twice. Escape it again and you get \\n, four characters, which looks like a bug and is in fact the only correct answer to the question that was asked. JSON has no way to know that you meant the first backslash as syntax rather than as content, and a tool that guessed would destroy every string that contains a genuine backslash, which on Windows paths is most of them.

This is the same shape of problem as double URL encoding, where %2520 decodes to %20 and looks like a failure — the URL decoder handles it by saying so before you read the result. This page does the same: it counts the escape sequences already present in your input, tells you before showing the output, and offers to run the unescape direction instead. Undoing a layer is a decision you make, never one the tool makes silently.

Emoji, surrogate pairs, and the trip back

Turning on ASCII-only output exposes a limit in JSON itself. The \uXXXX escape addresses one UTF-16 code unit and stops at four hexadecimal digits, so it cannot reach a character above U+FFFF directly. The spelling JSON does have is the surrogate pair: a party popper becomes \ud83c\udf89, two sequences that together mean exactly one character. Escaping and unescaping here writes and reassembles the pair, so one character goes in and one comes back. An escaper that walks code units without pairing them produces text that cannot be put back together, and it is a common enough bug that the round trip is worth checking with the Use as input button before you trust any tool, including this one.

The other characters worth naming are the ones you cannot see at all. Zero-width joiners, byte-order marks and non-breaking spaces all survive an escape untouched unless you ask for ASCII output, at which point they suddenly become visible as \u200d and friends. If a string is behaving strangely and you cannot see why, the invisible character inspector names each one rather than merely spelling it.

Where this sits among the JSON tools

This page works on a string — the contents of one value — and not on a JSON document. If you have a whole document to lay out over lines or strip back down, the JSON formatter is the tool for that, and if a parser has rejected your document and you want to know which dialect it actually is, the JSON validator names the rule that was broken. When the string you are escaping is destined for a JavaScript source file rather than a JSON payload, the rules differ slightly — single quotes, \x41, template literals — and the JavaScript to JSON converter handles that boundary at the document level, while the JavaScript escape tool writes a single string for single quotes, template literals and a </script> inside an inline script. If the string belongs in Java source, the Java escape tool also writes text blocks and avoids the unicode escape trap that breaks a line feed inside a literal. When the string is going into an HTML page instead, the backslashes are the wrong tool entirely: the HTML escape tool spells the same text with character references such as &quot; and &lt;. And if what you are staring at is not escaped text but base64, the base64 decoder is the other direction people commonly mistake this page for.

Nothing you paste here leaves your browser

Escaping is string arithmetic, and it happens on the machine you are reading this on. The site publishes no address that your text could be posted to, nothing you type or open is placed in the URL, and nothing is written to a log. That claim deserves stating plainly for this tool in particular, because the strings that need careful escaping are usually headed into a configuration file or an API request — which is exactly where connection strings, private keys, bearer tokens and customer records live. You can check it rather than take it: open your browser's network panel, paste something, and watch that no request appears, because there is nowhere for one to go.

Have an idea for this tool?

Tell us what would make this tool more useful, or suggest another tool you would like us to build.

Questions

Which characters have to be escaped in a JSON string?

Seven have a short spelling of their own: the backslash, the double quote, and the five control characters with names — line feed, carriage return, tab, backspace and form feed. Beyond those, JSON forbids every raw control character below U+0020 inside a string, so a null byte or a vertical tab has to be written as a numeric escape such as \u0000. Everything else is optional. Accented letters, emoji and every other character above ASCII are legal exactly as they are, and so is the forward slash — you will see \/ in the wild, but nothing requires it.

Why did my carriage returns disappear when I pasted?

They did not disappear here — they were gone before this page could see them. The HTML specification requires a textarea to normalize its raw value, which means every CRLF pair becomes a single line feed the moment the text lands in the field. No script can read what was there before, and no tool can work around it. That matters for JSON escaping more than for most jobs, because the whole question people bring here is often whether a file uses Windows line endings. Open the file with the file picker instead: reading a file gives the bytes as they are, CRLF included, and the counter on this page shows how many carriage returns survived so you can check rather than trust.

My string already contains \n and the tool doubled it. Is that a bug?

No, it is the correct answer to the question you asked. If your text literally contains a backslash followed by the letter n — two characters, not a line break — then escaping it for JSON has to produce four characters, \\n, because that is how JSON spells a literal backslash followed by an n. Feeding an already-escaped string through an escaper is a real mistake people make, usually when a value has passed through two layers of code, so this page counts the escape sequences it can already see in your input and says so before you read the result. The unescape direction undoes exactly one layer, and there is a button to run a second pass yourself rather than having the tool guess.

How does an emoji survive the trip?

An emoji is a single code point above U+FFFF, and JSON has no way to write one directly as a numeric escape — the \uXXXX form addresses one UTF-16 unit and stops at four hex digits. The spelling JSON does have is the surrogate pair, so a party popper becomes \ud83c\udf89: two sequences that together mean one character. This tool writes the pair when you ask for ASCII-only output and reassembles it when reading, so the round trip gives you one character back rather than two broken halves. A tool that escapes code unit by code unit without pairing them produces text that no parser can put back together.

Does the text I paste here leave my browser?

No. Escaping is string arithmetic, it happens on the machine you are reading this on, and the site publishes no address that text could be posted to. Nothing you type or open is put into the URL or written to a log. That is worth stating plainly for this tool in particular: the strings people need to escape are usually going into a config file or an API payload, which is exactly where connection strings, private keys and customer data live. You can check the claim rather than take it — open your browser devtools, watch the network panel, and paste something.