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
- Characters in
- —
- Sequences written
- —
- Characters out
- —
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
| Character | JSON writes it | Why |
|---|---|---|
| \ | \\ | A backslash starts every other escape, so it has to escape itself first. |
| " | \" | A double quote would end the string early. |
| LF | \n | Line feed. JSON forbids a raw control character inside a string. |
| CR | \r | Carriage return. Half of a Windows line ending, and the half that gets lost. |
| Tab | \t | Tab. Forbidden raw, and invisible when it survives. |
| Backspace | \b | Backspace, U+0008. |
| Form feed | \f | Form feed, U+000C. |
| / | \/ | Optional. Only needed when the JSON sits inside a <script> tag, where the text </script> would close it. |
| anything else | \uXXXX | Every 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
" and <. 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.
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.