One Emoji, Three Escape Notations: JS vs JSON vs Python
๐ To safely embed the same emoji in a source-code string, you need escape syntax โ but that syntax differs across JavaScript, JSON, and Python. That's exactly why copying an escaped string from one language and pasting it into another can throw a parsing error. We checked the actual code behind the Unicode Converter to see what notation this tool generates, and laid out precisely what each language's rules are.
1. Why the notations diverge: the BMP and everything beyond it
Unicode code points range from U+0000 to U+10FFFF, but the classic \uXXXX escape holds exactly 16 bits โ 4 hex digits โ so it can only represent U+0000 through U+FFFF (the Basic Multilingual Plane, or BMP). Most emoji sit at U+1F300 or higher, well outside that range, so each language had to come up with its own answer to "how do we notate characters outside the BMP?"
2. JavaScript: supports two notations
Since ES6, JavaScript has additionally supported a dedicated syntax for characters outside the BMP: \u{code point} (curly braces). At the same time, the older surrogate-pair approach โ writing a character like ๐ as two consecutive 4-digit escapes โ remains valid for backward compatibility. So within JS, there are two ways to notate the same character.
3. JSON: only surrogate pairs, no curly-brace syntax
The JSON spec (RFC 8259) defines only the 4-digit \uXXXX escape โ JS's curly-brace \u{...} syntax doesn't exist in JSON's grammar at all. So characters outside the BMP must be split into a pair of surrogate escapes. Whenever JSON.stringify() encounters an emoji, this is the format it always uses.
4. Python: an uppercase U + 8 fixed digits
Python takes yet another approach. Lowercase \u is 4 digits (BMP only) just like in JS, but for characters outside the BMP, Python doesn't use surrogate pairs โ it writes the entire code point at once with an uppercase \U plus 8 hex digits. Python strings are handled as a sequence of code points rather than UTF-16, so the surrogate-pair concept isn't needed at all.
| Language/format | Notation | Character count | Note |
|---|---|---|---|
| JavaScript (ES6 curly-brace) | \u{1F600} | 1 code point | Syntax error in JSON |
| JavaScript (surrogate pair, legacy-compatible) | ๐ | 2 code units | Also valid in JSON |
| JSON | ๐ | 2 code units | Only this notation supported, no curly braces |
| Python | \U0001F600 | 1 code point | Uppercase U, must be 8 digits |
As the table shows, if you paste JS's \u{1F600} directly into a JSON string, the JSON parser doesn't recognize the syntax and throws a parsing error. Conversely, JS's surrogate-pair notation (๐) remains valid in JSON as-is โ but pasting Python's \U0001F600 into either of the other two languages will also cause a syntax error. "Same character, different notation" is exactly where copy-pasting code between languages trips people up.
5. What notation does the Unicode Converter actually generate?
Checking the actual conversion logic in unicode-converter.html shows that the "JS \uXXXX" output column automatically switches between the two syntaxes depending on the code point value.
const jsArr=chars.map(c=>{const cp=c.codePointAt(0);return cp<=0xFFFF?'\u'+cp.toString(16).padStart(4,'0').toUpperCase():'\u{'+cp.toString(16).toUpperCase()+'}';});When the code point is 0xFFFF or below (inside the BMP), it generates the classic 4-digit
\uXXXX; when it exceeds 0xFFFF, it generates the ES6 curly-brace form \u{code point}. This tool doesn't offer a separate column for the JSON-style surrogate pair or Python's \U notation โ its purpose is specifically to produce "notation usable in a JS string literal."
So if you take the \u{1F600} notation the Unicode Converter generates and paste it directly into a JSON config file or API payload, you'll get a parsing error. If you need a JSON-ready string, run the value through JSON.stringify() once, or use the U+ code point value the tool also provides to compute the surrogate pair yourself. Conversely, if you paste a surrogate pair (๐) into the input box, this tool correctly restores it with String.fromCodePoint() and recognizes it as a single character via code-point-based iteration, decoding it correctly.
6. How to avoid errors when copying code between languages
- If the target is a JSON string or config file, you must use surrogate-pair notation (
๐) only โ curly-brace syntax won't work. - If the target is JS source code, both notations work, but if an ES6+ environment is guaranteed, curly-brace notation reads better.
- If the target is Python source code, you must use uppercase
\Uplus 8 digits โ the lowercase 4-digit\ucan't represent characters outside the BMP and will cause a truncation error. - When in doubt, the safest approach is to convert manually to the target language's syntax based on the U+ code point (e.g. U+1F600). You can also round-trip verify using the Text-to-Unicode Converter and Unicode-to-Text Converter.
FAQ
Q. Can I paste the \u{1F600} notation the Unicode Converter generates directly into JSON?
No. The JSON spec doesn't support curly-brace code point syntax, so it will throw a parsing error. You need to convert it to surrogate-pair notation (๐) instead.
Q. Can I use Python's \U0001F600 in JavaScript?
Not as-is. JS doesn't recognize the uppercase \U 8-digit syntax. To represent the same code point, you'd need to rewrite it as \u{1F600} or ๐.
Q. Are characters within the BMP (e.g. Korean, Latin letters) notated the same way across languages?
Yes. Characters at or below U+FFFF are all notated identically as lowercase 4-digit \uXXXX in JS, JSON, and Python, with no need for surrogate pairs or curly-brace syntax โ they're compatible across languages. The mismatches only ever happen with characters outside the BMP.
Q. If I paste a surrogate pair into the input box, does this tool restore it correctly?
Yes. It uses String.fromCodePoint() to combine the high and low surrogates into a valid character, then recognizes it correctly as a single character via code-point-based iteration.