Unicode Encoder Decoder
Convert between text, Unicode escapes, and U+ notation while keeping surrogate pairs and normalization differences visible.
Encode as
Output
Encoded or decoded Unicode output will appear here.
No output yet.
“One Character” Can Mean Four Different Counts
A user sees text as grapheme clusters: what appears to be one character on screen can be several Unicode code points. JavaScript strings are indexed as UTF-16 code units. UTF-8 stores those scalar values as one to four bytes. None of those counts is guaranteed to equal the number of visible symbols.
The emoji 😀 is one Unicode scalar value, two UTF-16 code units, and four UTF-8 bytes. A family emoji or an accented letter written with a combining mark can involve several code points while still looking like one user-perceived character.
Why 😀 Becomes Two \uXXXX Escapes but One U+1F600
Unicode code point
U+1F600
UTF-16 code units
D83D DE00
Four-digit escape representation
\uD83D\uDE00
JavaScript code-point escape
\u{1F600}Four-digit \uXXXXescapes represent UTF-16 code units. A code point above U+FFFF therefore needs a high-surrogate and low-surrogate pair. JavaScript's brace form can spell the code point directly, but that \u{...} form is not JSON syntax.
Surrogate Code Points Exist, but They Are Not Standalone Unicode Characters
U+D800 through U+DFFF are reserved for UTF-16 surrogate mechanics. The Unicode Standard calls all values from U+0000 through U+10FFFF code points, but excludes surrogate code points from the set of Unicode scalar values. An isolated UTF-16 surrogate code unit has no standalone character interpretation.
Strict decode mode therefore rejects lone surrogates. Inspection mode can preserve them in a JavaScript string when you are diagnosing malformed or legacy data, while clearly marking that result as ill-formed Unicode text.
JSON Can Contain a \uD800 Escape Even Though Interoperability Is Poor
JSON's ABNF permits a four-hex-digit \uXXXX escape, and RFC 8259 notes that observed JSON texts can contain unpaired surrogate escapes such as \uDEAD. The RFC also warns that software behavior for those values is unpredictable.
That is why “valid-looking JSON escape syntax” and “well-formed Unicode scalar text” are not exactly the same claim. The decoder defaults to the stricter Unicode interpretation rather than silently normalizing malformed surrogate data.
JavaScript \u{...} Syntax Describes a Code Point, Not UTF-8 Bytes
\u{1F600} is an ECMAScript source escape. The hexadecimal number identifies a Unicode code point up to U+10FFFF. It does not show the UTF-8 byte sequence F0 9F 98 80, and it is not a percent-encoded URL sequence.
Choose the representation based on the system you are debugging: JavaScript source, JSON-style UTF-16 escapes, U+ notation in documentation, or UTF-8 bytes on the wire are different layers.
Two Strings Can Look the Same and Still Have Different Code Points
The visible letter é can be represented as U+00E9 or as U+0065 followed by U+0301 COMBINING ACUTE ACCENT. Unicode normalization defines standard transformations such as NFC and NFD for equivalent sequences.
The normalization check reports whether NFC or NFD would change the supplied sequence, but it does not normalize automatically. Silent normalization would make an encoder stop being a faithful representation of the exact string you pasted.
Bidirectional Controls Can Change Display Order Without Changing Stored Order
Characters such as U+202E RIGHT-TO-LEFT OVERRIDE and the isolate controls U+2066 through U+2069 affect how surrounding text is displayed. They do not rearrange the underlying code-point sequence, so copied text can look different from the order a parser reads.
The inspection table names common bidirectional controls instead of placing the invisible control itself in the Display column. That makes source review safer while leaving the actual input and output untouched. The Unicode Bidirectional Algorithm defines how these controls participate in rendering.
TextEncoder Has to Repair Lone Surrogates Before Producing UTF-8
UTF-8 encodes Unicode scalar values; surrogate code points are not scalar values. JavaScript strings, however, can contain lone UTF-16 surrogate code units. Web APIs that turn such strings into Unicode scalar text generally use well-formed-string behavior, which can replace lone surrogates with U+FFFD.
The inspection table does not pretend those replacement bytes were the original character. It labels a lone surrogate as not directly representable as a Unicode scalar value.
Unicode, JSON, and JavaScript Define Different Parts of the Problem
Unicode's core specification defines code points, surrogate code units, surrogate pairs, scalar values, UTF-16, and UTF-8. Unicode 17 Core Specification, Chapter 3. Bidirectional formatting is specified separately in Unicode Standard Annex #9. For syntax boundaries, RFC 8259 covers JSON string escapes and surrogate interoperability, while the ECMAScript lexical grammar defines JavaScript's Unicode escape forms.
