Skip to main content

A Practical Guide to the Unicode Inspector: Reading Text by Code Points

Inspect any text character-by-character: code points, names, categories, and UTF-8/UTF-16 bytes. Find hidden zero-width glyphs and look-alike homoglyphs fast.

Published By Li Lei
#unicode #encoding #debugging #security #developer-tools

A Practical Guide to the Unicode Inspector: Reading Text by Code Points

Text is not what it looks like. The string you read on screen is a rendered picture; underneath it sits a sequence of code points, and two strings that look identical can be made of completely different bytes. When that mismatch causes a bug, staring at the editor will never reveal it, because the thing breaking your code is, by definition, something you cannot see.

The Unicode Character Inspector splits any text into its real parts and shows you what each one actually is. Paste a string and every character gets a row: the glyph, its code point, its official name, its general category, and the exact UTF-8 and UTF-16 bytes it occupies. That per-character view is the difference between guessing and knowing.

Every character has three facts worth knowing

Open the inspector and type the letter A. The tool tells you three things that, together, identify it without ambiguity:

  • Code pointU+0041, the number Unicode assigns to it.
  • Official nameLATIN CAPITAL LETTER A, the canonical label from the Unicode database.
  • General categoryLu (Letter, uppercase), the classification that controls how parsers, regexes, and case-folding treat it.

Those facts matter because the rendered shape is a poor identifier. A capital Latin A (U+0041) and a Cyrillic А (U+0410) draw the same picture in almost every font, yet they are different characters with different names and different bytes. The code point is the only fact that does not lie. When you compare two characters by their U+XXXX values, the look-alike problem disappears instantly.

Bytes: UTF-8, UTF-16, and why the counts disagree

The same character occupies a different number of bytes depending on the encoding, and the inspector shows all of them per character. The letter A is one UTF-8 byte (41) and one UTF-16 code unit. The em dash (U+2014) is three UTF-8 bytes (E2 80 94) but still one UTF-16 unit. A musical G-clef 𝄞 (U+1D11E) lives above U+FFFF, so it is four UTF-8 bytes and a surrogate pair of two UTF-16 units.

This is exactly why naive length checks fail. In JavaScript, '𝄞'.length returns 2, not 1, because length counts UTF-16 units. If you are sizing a database column or enforcing a "280 character" limit, you need the code-point count or the grapheme count, never the UTF-16 unit count. The inspector's summary tallies graphemes, code points, and UTF-8 bytes side by side so you pick the right number for the job. Once you understand the byte math here, related conversions in tools like text to binary stop feeling like black boxes.

Finding the characters you cannot see

The most valuable column is the one that flags trouble. Two classes of character cause most "impossible" text bugs:

  • Invisible characters — zero-width spaces (U+200B), zero-width joiners (U+200D), the byte order mark (U+FEFF), no-break spaces (U+00A0), and right-to-left overrides (U+202E). They render as nothing, or as a normal-looking space, yet they break parsers, comparisons, and filename safety.
  • Confusables (homoglyphs) — characters from other scripts that mimic basic Latin letters. A Cyrillic а (U+0430) looks exactly like a Latin a (U+0061); a Greek ο looks like a Latin o. These power domain spoofing, username squatting, and homograph phishing.

The inspector gives each of these a colored flag right next to its code point, so a string that "looks normal" gets a per-character verdict instead of your blind trust.

A worked example: the username that was already taken

Here is a problem I hit while debugging a signup flow, and it is the example that convinced me to keep this tool one tab away. The form rejected the username paypal as already taken, but our admin panel showed no such account. Two engineers compared the strings by eye for ten minutes and swore they were identical.

I pasted both into the inspector. The new signup was plain ASCII: p a y p a l, six code points, U+0070 through U+006C, all category Ll. The existing account told a different story. Its third character was not the Latin y (U+0079) — it was the Cyrillic у (U+0443, CYRILLIC SMALL LETTER U), flagged red as a confusable. Someone had registered a look-alike to squat the name. There was also a trailing U+200B ZERO WIDTH SPACE on the stored value, invisible everywhere except here, which is why even a careful copy-paste comparison missed it.

The fix took two minutes once I could see it: normalize incoming usernames to a single script and strip zero-width characters before the uniqueness check. Without per-character code points, that bug would have outlived the sprint.

Building precise output: entities and escapes

Inspecting text is only half the job; sometimes you need to produce an exact character without pasting a raw glyph a teammate's editor might mangle. Each row in the inspector gives you the copyable forms: the named HTML entity (—), the numeric entities (— and —), and the JavaScript escape (, or \u{1F600} for astral characters). One click copies the exact form your file needs.

When the task is bulk encoding rather than single-character lookup, hand off to a dedicated tool. For wrapping whole strings of markup-sensitive text, the HTML entities encoder is the better fit. For percent-encoding text headed into a URL, reach for the URL encoder instead. The inspector is where you go to understand a single tricky glyph; the encoders are where you process text in volume.

Debugging encoding bugs, step by step

When text behaves strangely, the inspector turns a vague symptom into a concrete cause. A reliable routine:

  1. Reproduce with the smallest string. If a JSON loader throws unexpected token on line 1, paste just that line.
  2. Scan the summary first. A code-point count that exceeds the visible character count means hidden characters are present.
  3. Read the flagged rows. A U+FEFF BOM before the opening brace, or a U+00A0 no-break space where you expected U+0020, is the usual culprit — both invisible in most editors.
  4. Copy the precise code point. Use the exact U+XXXX value to write a surgical replace, rather than a blunt regex that misses the invisible variants of "space".

This same per-character clarity helps far beyond bug fixing. When you are auditing user-supplied display names, coupon codes, or domain labels for spoofing, the confusable and right-to-left-override flags give you a defensible verdict before the text reaches production. And if your investigation drifts toward emoji specifics — why a single family emoji costs seven code points — the emoji finder complements the inspector by helping you locate the exact glyph you meant.

Unicode is deep, but you rarely need to read the standard. You need to see, for one specific string, what each character truly is. That is the whole job of the inspector: make the invisible visible, the ambiguous exact, and the look-alike obvious.


Made by Toolora · Updated 2026-06-13