Skip to content

Unicode Converter

Paste any Unicode form and read it back as text. \uXXXX escapes, ES6 braces, U+ code points, entities and byte runs are recognised automatically, then every other representation is listed at once. Runs in your browser.

No Tracking Runs in Browser Free

Everything runs in your browser — your input is never uploaded, logged, or stored.

0 chars
Readable text
Result appears here
Normalize
Every representation at once
JavaScript / Java / JSON uXXXX
ES6 u{XXXXX}
Python uXXXX / UXXXXXXXX
Go uXXXX / UXXXXXXXX
Rust u{XXXXX}
Code point U+XXXX
HTML decimal &#NNNNN;
HTML hex &#xXXXX;
URL encoded %XX
CSS XXXXXX
UTF-8 bytes hex
UTF-16 units hex
UTF-32 hex
Octal bytes NNN
Decimal code points NNNNN
Character by character
Char Code point UTF-8 UTF-16 Script Category Name
Result appears here

Quick reference

Char Code point JavaScript / Java / JSON UTF-8 bytes URL encoded HTML decimal
中文 U+4E2D U+6587 \u4E2D\u6587 E4 B8 AD E6 96 87 %E4%B8%AD%E6%96%87 中文
😀 U+1F600 \uD83D\uDE00 F0 9F 98 80 %F0%9F%98%80 😀
A U+0041 A 41 A A
U+3000 U+3000 \u3000 E3 80 80 %E3%80%80  
Every conversion in the reference table was cross-checked between two independent implementations before publication. — Go Tools Engineering · Aug 27, 2026

Behaviour verified against Node, Python, Java, Go and a real browser engine rather than assumed from documentation.

What is a Unicode escape?

A Unicode escape writes a character using only ASCII, so it survives systems that cannot carry the character itself. The same character has a different escape in almost every language: JavaScript and JSON use four hex digits per UTF-16 unit, ES6 and Rust take a full code point in braces, Python and Go add a wide eight-digit form, CSS uses a bare backslash, and HTML has its own numeric and named references. They all describe the same code point, which is why one string can arrive at you in half a dozen shapes.

中文
  U+4E2D U+6587         code point
  \u4E2D\u6587          JavaScript / Java / JSON
  \u{4E2D}\u{6587}      ES6 / Rust
  E4 B8 AD E6 96 87     UTF-8
  %E4%B8%AD%E6%96%87    URL
  中文      HTML

What this converter does

Recognises the form for you

Escapes, braces, wide escapes, code points, entities, percent-encoding and byte runs are detected without a mode switch.

Survives mixed input

Only the encoded parts change. JSON punctuation, Windows paths and already-escaped backslashes are left as they are.

Every representation at once

One paste produces the whole table, so you never convert twice to get from one language to another.

Per-language correctness

Characters outside the BMP are written as a wide escape for Python and Go, where a surrogate pair would fail.

Character-level inspection

Code point, UTF-8 and UTF-16 bytes, script and category for every character, plus the Unicode name wherever there is one.

Reveals invisible characters

Byte order marks, zero-width joiners and non-breaking spaces get a visible stand-in.

Examples

Decode a log line without touching the rest of it

{"msg":"\u4e2d\u6587 failed","code":500}
{"msg":"中文 failed","code":500}

Only the escape sequences change. Quotes, keys and numbers are left exactly as they were, so you can paste a whole log line instead of picking the escapes out by hand.

Mixed representations in one paste

U+4E2D  \u{1F600}  中  \ud83d\ude00
中  😀  中  😀

A code point, an ES6 brace escape, an HTML entity and a surrogate pair, all decoded in one pass. Nothing had to be selected or configured first.

One character, every representation

\u4E2D        JavaScript / Java / JSON
\u{4E2D}      ES6 / Rust
U+4E2D        code point
E4 B8 AD      UTF-8
\344\270\255  octal

The same character written the way each language expects it. Note that Python and Go need the wide form for characters outside the BMP — a surrogate pair will not compile in Go and raises UnicodeEncodeError in Python.

How to use

  1. 1

    Paste

    Drop in escapes, code points, entities, encoded bytes or plain text. No need to say which one it is.

  2. 2

    Read the result

    The readable text appears immediately, with a note of which representations were recognised.

  3. 3

    Copy the form you need

    Every representation is listed below the result, each with its own copy button.

  4. 4

    Inspect if something looks wrong

    Open the character table to see code points, bytes, script and names, and switch on Reveal to expose invisible characters.

Mistakes worth knowing about

Writing a surrogate pair where the language wants a wide escape

A pair that works in JSON becomes two broken halves in Python and refuses to compile in Go. Use the wide form for characters above U+FFFF.

✗ Wrong
\ud83d\ude00
✓ Correct
\U0001F600

Decoding HTML numeric references as plain code points

References between 128 and 159 must be read through windows-1252. A naive implementation turns a right single quotation mark into an invisible control character, which is why those spots in an old export render as nothing at all.

✗ Wrong
’  ->  U+0092
✓ Correct
’  ->  U+2019

Using a short CSS escape before a hex character

The parser keeps eating hex digits, so the escape and the next character merge into a single wrong code point. Pad to six digits.

✗ Wrong
\4E2Da
✓ Correct
\004E2Da

When you need it

Reading logs
Server logs and API responses often arrive with non-ASCII escaped. Paste the line and read it without editing it first.
Moving strings between languages
Copy the escape in the exact form the target language accepts, instead of hand-converting between surrogate pairs and wide escapes.
Chasing an encoding bug
When a comparison fails or a database rejects a value, the character table shows exactly which code points and bytes are involved.
Cleaning pasted content
Text copied from a web page or a document often carries invisible characters. Find them before they reach production.

Technical details

UTF-16 units, not characters
JavaScript, Java and JSON escape UTF-16 code units, so a character above U+FFFF needs two escapes. Python and Go instead offer an eight-digit form that takes the code point directly.
HTML numeric references are remapped
The HTML specification requires numeric references in the 128 to 159 range to be read through windows-1252 rather than as code points, so a reference like 146 is a right single quotation mark rather than an invisible control character.
CSS escapes need padding
A CSS escape consumes up to six hexadecimal digits, so a short escape followed by a hex character merges into one wrong code point. Padding to six digits removes the ambiguity, and a following space is consumed as a terminator.
Unpaired surrogates behave differently everywhere
An unpaired surrogate is preserved by JSON stringification, silently replaced by TextEncoder, rejected by percent-encoding, written as a question mark by Java and raised as an error by Python.

Best practices

Normalise before comparing
Fold both sides to the same normalisation form before comparing or deduplicating, especially for names and identifiers.
Prefer the wide form for Python and Go
A surrogate pair is valid in JSON but breaks in both languages. Use the eight-digit escape when the target is Python or Go source.
Check for invisible characters early
Validate pasted input at the boundary rather than debugging a mismatch later.
Keep the original around
Decoding is not always reversible in a lossless way once replacement characters appear. Keep the raw value until you are sure.

Frequently asked questions

What does \u4e2d\u6587 mean and how do I read it?
Each \uXXXX is one UTF-16 code unit written in hexadecimal. \u4e2d is U+4E2D and \u6587 is U+6587, which together spell a Chinese word. Paste the whole string above and the readable text comes back; surrounding JSON or log text is preserved untouched.
The backslashes were stripped and I only have u4e2d left. Can that still be decoded?
Yes. Terminals and log pipelines often swallow backslashes. Bare u4e2du6587 is recognised and decoded, while ordinary words that merely contain a u are left alone.
Why is one emoji written as two \u escapes?
Characters above U+FFFF do not fit in a single UTF-16 code unit, so JavaScript, Java and JSON write them as a surrogate pair. A grinning face is one code point, two UTF-16 units and four UTF-8 bytes. The character table shows all three counts.
How do I go the other way and turn text into escapes?
Type or paste plain text and read the table below the result. Every representation is produced at once, so you can copy the exact form your language expects instead of converting twice.
Two strings look identical but my code says they are different. Why?
They are probably normalised differently. An accented letter can be one code point or a base letter plus a combining mark; both render the same but are not equal. Use the NFC button to fold them together. Note that normalisation is not a no-op for CJK either — compatibility ideographs change under plain NFC.
Something invisible in my string is breaking my code. How do I find it?
Turn on Reveal invisible characters. Byte order marks, zero-width spaces, non-breaking spaces and variation selectors get a visible stand-in, and the character table names each one and gives its bytes.
Is my data uploaded anywhere?
No. Conversion happens in your browser with no network request. Nothing is uploaded, logged or stored, so pasting production logs is safe.

Related Tools

View all tools →