JSON Escape & Unescape
Escape plain text into a valid JSON string literal, decode an escaped literal back to readable text, and get a JavaScript-source-safe variant. No upload.
Input
How it works
- Escape serializes the input with JSON.stringify: quotes, backslashes, newlines, tabs and control characters become the short \u-escapes that JSON requires, wrapped in double quotes.
- Unescape parses the literal back with JSON.parse, restoring the original text — handy for decoding API logs, CSV dumps, or generated payloads.
- The For JavaScript source row shows the same literal with U+2028 and U+2029 also escaped, so the string is safe to paste into older JS engines that reject those characters in source code.
- Byte counts (UTF-8) for input and output are shown under the result.
About JSON Escape & Unescape
Escaping is the price of putting arbitrary text inside a JSON document: quotes and backslashes must be marked, and control characters cannot appear literally. Getting the escaping wrong produces invalid JSON — a leading cause of broken configs, failed API calls, and corrupted import scripts.
This tool removes the guesswork. Escape raw text before embedding it in a config file, a request body, or a test fixture; unescape when you pull an escaped literal out of logs and want to read it. Both directions run locally, so sensitive payloads never leave your browser.
What the two directions actually do
Escape mode is a single `JSON.stringify` call on the raw input, so the output is always a complete, quoted JSON string literal rather than a bare fragment. Only what JSON requires is escaped: the double quote, the backslash, and the C0 control range. Tabs become `\t`, newlines become `\n`, and any other character below U+0020 becomes a `\u00XX` escape. Ordinary non-ASCII text is passed through untouched rather than being escaped to `\u` form.
Unescape mode is the inverse `JSON.parse`. If the trimmed input starts with a double quote it is parsed as-is; otherwise quotes are wrapped around it first, so you can paste `He said "hi"` without supplying the delimiters. A malformed escape produces a parse error instead of a partial result, which is the behaviour you want when auditing log output or a corrupted config value.
The JavaScript-source variant and byte counts
The second output row additionally escapes U+2028 and U+2029. Both are legal inside a JSON string, but historically rejected by JavaScript parsers in string-literal position, so output pasted into source, a shell argument, or an inline script can break on engines that predate the JSON-superset change. The primary row deliberately leaves them alone, since escaping them would misrepresent the JSON.
Byte counts are measured with `TextEncoder`, so they report UTF-8 rather than JavaScript string length. That distinction matters for non-ASCII input: a CJK character is one length unit but three bytes, and an emoji outside the basic plane is two units and four bytes. The input and output figures together tell you exactly what the escaping cost.
Where escaping goes wrong in practice
The common failure is wrong scope rather than wrong characters. Escaping yields a `"…"` string literal, not a JSON document, so pasting the output where a document is expected gives you a quoted scalar instead of the object you intended. To embed a value into an existing JSON file, escape only the string fragment and assemble the surrounding punctuation, commas and braces yourself.
Note also that the forward slash is never escaped, because JSON does not require it. The `</script>` sequence that matters when embedding JSON inside an HTML script block therefore passes through verbatim — escape it by hand if that is your target, and remember that an unescaped newline inside a JSON string is what turns a valid config into a parse error.
Frequently Asked Questions
How do I escape JSON special characters?
Why do I need to escape JSON?
Is my data sent to a server?
Do I need an account or API key?
Can I use these tools offline?
All processing happens in your browser. No uploads, no tracking, no servers. Your API keys, configs, and private payloads stay private — 100% client-side.