JSON Escape / Unescape
Turn any text into a valid JSON string, or turn an escaped JSON string back into raw text. The escape presets reproduce what each language's serializer actually emits — measured, not guessed — so you can match Go, Python or .NET output exactly.
Result will appear here
What each serializer escapes by default
RFC 8259 §7 requires only three things to be escaped: the quotation mark, the reverse solidus, and the control characters U+0000–U+001F. Everything else is a serializer's choice — and they disagree. The table below was produced by running each serializer on the same inputs. Amber means the character was changed.
| Serializer | é (U+00E9) | 😀 (U+1F600, astral) | < > & (HTML-significant) | ' (apostrophe) | / (solidus) | U+2028 LINE SEPARATOR | U+007F DELETE |
|---|---|---|---|---|---|---|---|
| JavaScript · V8 (Node, Chrome) | é | 😀 | <a>&b | it's | a/b | (raw) | |
| JavaScript · JavaScriptCore (Safari) | é | 😀 | <a>&b | it's | a/b | (raw) | |
| Python · json.dumps() default | \u00e9 | \ud83d\ude00 | <a>&b | it's | a/b | \u2028 | \u007f |
| Python · ensure_ascii=False | é | 😀 | <a>&b | it's | a/b | (raw) | |
| Go · encoding/json v1 | é | 😀 | \u003ca\u003e\u0026b | it's | a/b | \u2028 | |
| Go · SetEscapeHTML(false) | é | 😀 | <a>&b | it's | a/b | \u2028 | |
| Java · Jackson | é | 😀 | <a>&b | it's | a/b | (raw) | |
| Java · Gson | é | 😀 | \u003ca\u003e\u0026b | it\u0027s | a/b | \u2028 | |
| .NET · System.Text.Json | \u00E9 | \uD83D\uDE00 | \u003Ca\u003E\u0026b | it\u0027s | a/b | \u2028 | \u007F |
| .NET · Newtonsoft.Json | é | 😀 | <a>&b | it's | a/b | \u2028 | |
| PHP · json_encode() | \u00e9 | \ud83d\ude00 | <a>&b | it's | a\/b | \u2028 | |
| Ruby · JSON.generate | é | 😀 | <a>&b | it's | a/b | (raw) | |
Node.js 22, CPython 3.12, Go 1.22, Java 21 (Jackson 2.14 / Gson 2.10), .NET 8 (System.Text.Json / Newtonsoft.Json 13), PHP 8.3, Ruby 3.2, JavaScriptCore via Bun 1.4.
Three surprises in that table
Go escapes <, > and &
json.Marshal turns them into \u003c, \u003e and
\u0026 so JSON can be embedded in HTML without a browser reinterpreting it.
Use an Encoder with SetEscapeHTML(false) to stop it. Go's
encoding/json/v2 drops this default.
Python and PHP escape all non-ASCII
json.dumps() defaults to ensure_ascii=True, so café
becomes caf\u00e9. Pass ensure_ascii=False for UTF-8 output. PHP needs
JSON_UNESCAPED_UNICODE, and JSON_UNESCAPED_SLASHES to stop
/ becoming \/.
Gson and .NET escape the apostrophe
Both turn ' into \u0027. Jackson does not. If you are diffing
Gson output against Jackson output byte-for-byte, this is usually why they differ.
What the specification requires
- RFC 8259 (STD 90) §7 — Strings
— fixes the escape set (
\" \\ \/ \b \f \n \r \tand\uXXXX) and requires the quotation mark, reverse solidus and U+0000–U+001F to be escaped. Everything else is optional. - RFC 8259 §8.1 — Character Encoding — JSON exchanged between systems must be UTF-8, which is why escaping non-ASCII is a choice rather than a requirement.
- RFC 8259 §8.2 — Unicode Characters — describes the unpaired surrogate case this tool rejects when unescaping.
- RFC 8259 §12 — Security Considerations — names U+2028 and U+2029 as legal in JSON but illegal in JavaScript. That is why several serializers escape them and the JavaScript engines do not.
- ECMA-404, 2nd edition §9 — Strings — Ecma International's grammar for the same rules, with the escape table.
Why the twelve serializers above disagree, and which differences have a security angle: Every JSON serializer escapes differently →
Everything on this page runs in your browser — no upload, no server-side processing. How it works →