The Unicode Inspector, Explained

After reading this, you will be able to read a string as a sequence of Unicode codepoints, spot the invisible characters that break searches and diffs, and understand why two words that look identical can fail to match.

What a Unicode inspector shows you

Text on a screen is a drawing. Underneath, a string is a sequence of numbers called codepoints. Each codepoint has an official name, belongs to a named block, and is stored on disk as one to four bytes of UTF-8. A Unicode inspector breaks your string back into that sequence so you can see what is really there, not just what the font paints.

Here is the hook. Consider the two strings café and café. They can look pixel-identical. One is four codepoints: c, a, f, and U+00E9 (LATIN SMALL LETTER E WITH ACUTE). The other is five codepoints: c, a, f, e, then U+0301 (COMBINING ACUTE ACCENT) stacked on the e. A plain string search for one will not find the other. A diff will report a change where you see none. The inspector shows the difference at a glance because it lists five items instead of four.

When to use it, and when not to

Reach for the inspector when text behaves in a way the eye cannot explain. A password field rejects what looks like the right password. A CSV column will not join to another table even though the values match on screen. A regular expression that should fire does not. A search for "co-operate" misses a copy that contains a soft hyphen. These are all invisible-character problems, and the inspector is built for them.

Do not use it for ordinary counting or reading work. If you want words, sentences and reading time, use the Word & Character Counter. If you want to compare two documents line by line, use the Text Diff Checker. The inspector answers one question well: what are the exact codepoints, and which ones are suspect.

Codepoints, bytes and the numbers behind them

A codepoint is a number in the range 0 to 1{,}114{,}111 (that is 0 to 0x10FFFF). It is written U+ followed by at least four hex digits, so the letter A is U+0041 and the grinning face emoji is U+1F600. UTF-8 encodes each codepoint using a variable number of bytes:

n_{\text{bytes}} = \begin{cases} 1 & \text{if } cp \le \text{0x7F} \\ 2 & \text{if } cp \le \text{0x7FF} \\ 3 & \text{if } cp \le \text{0xFFFF} \\ 4 & \text{otherwise} \end{cases}

Here cp is the codepoint value. The rule explains why a byte count and a character count disagree so often. Plain ASCII (U+0000 to U+007F) costs one byte each. Accented Latin, Greek and Cyrillic letters cost two. Most CJK characters and the majority of symbols cost three. Emoji and rarer scripts cost four.

The words "character", "codepoint", "byte" and "grapheme" are not synonyms. The family emoji 👨‍👩‍👧 is one grapheme (one thing you see), but it is five codepoints joined by zero-width joiners, and 18 UTF-8 bytes. Counting depends entirely on which unit you mean.

A worked example with the demo text

Reading "café" the hard way

Take the composed and decomposed forms of café and lay out every codepoint.

Two spellings of the same-looking word
FormCodepointNameUTF-8 bytes
ComposedU+0063LATIN SMALL LETTER C63
U+0061LATIN SMALL LETTER A61
U+0066LATIN SMALL LETTER F66
U+00E9LATIN SMALL LETTER E WITH ACUTEC3 A9
DecomposedU+0065LATIN SMALL LETTER E65
U+0301COMBINING ACUTE ACCENTCC 81
  1. The composed form is 4 codepoints. Its byte count is 1 + 1 + 1 + 2 = 5 bytes, because U+00E9 is above 0x7F and costs two bytes.
  2. The decomposed form is 5 codepoints. Just the tail (e plus combining accent) is 1 + 2 = 3 bytes, so the whole word is 1 + 1 + 1 + 3 = 6 bytes.
  3. Same picture, different codepoint count (4 vs 5), different byte count (5 vs 6). A byte-for-byte comparison reports them as unequal.

The fix is normalization. Unicode defines NFC (composed) and NFD (decomposed) forms in the Unicode Standard Annex #15. Converting both strings to NFC makes them identical, which is why databases and search engines normalize before they compare.

The troublemakers, and how to read the flags

Most of the damage comes from a short list of characters that render as nothing, or as an ordinary space, or as a letter they are not. The inspector flags these.

Zero-width space (U+200B)
Renders as no width at all. Splits a word invisibly, so help​desk fails to match helpdesk. Costs 3 bytes.
Non-breaking space (U+00A0)
Looks exactly like a normal space (U+0020) but is a different codepoint. Common in text copied from Word and PDFs. Breaks split(" ") and trims that expect U+0020.
Soft hyphen (U+00AD)
An invisible "you may hyphenate here" marker. Invisible until a line wraps, then it may print a hyphen. Poisons search inside words.
Bidi controls (U+202A to U+202E, U+2066 to U+2069)
Reorder text direction. U+202E (RIGHT-TO-LEFT OVERRIDE) can make a filename display backwards, a classic trick for disguising file extensions.
Confusables (lookalikes)
Cyrillic а (U+0430) versus Latin a (U+0061). Identical shape, different codepoint. The basis of many spoofed domain names, described in Unicode Technical Standard #39.

A non-breaking space is the single most common cause of "these two cells look equal but will not join". It is U+00A0, not U+0020. Screen and eye cannot tell them apart, so you must inspect the codepoints.

Why one byte count is never the whole story

The chart below shows how many UTF-8 bytes different codepoints cost. Notice the flat steps: every codepoint in a range costs the same number of bytes, and the jumps happen at 0x7F, 0x7FF and 0xFFFF.

The letter A costs 1 byte, é costs 2, a common CJK character costs 3, and an emoji costs 4.

This is why a 280-character limit and a 280-byte limit are different rules. A tweet of 280 emoji is 280 codepoints but 1,120 bytes. A field sized for 255 bytes holds 255 ASCII letters, or about 127 accented letters, or 85 CJK characters, or 63 emoji.

Explore how invisible characters change a string

Start with helpdesk: 8 codepoints, 8 bytes, and it matches the search term "helpdesk". Insert one zero-width space (U+200B) between "help" and "desk" and you now have 9 codepoints and 11 bytes, still 8 visible characters, and the search no longer matches. Replace it with a non-breaking space (U+00A0) and the string shows a gap but a search for a normal space still fails.

Common mistakes

The first mistake is trusting the eye. If two strings look the same but behave differently, assume a hidden codepoint until the inspector proves otherwise. The second is confusing units, as covered above: reporting "characters" when a system counts bytes, or vice versa, produces off-by-a-lot errors on non-ASCII text.

The third is over-cleaning. A non-breaking space is often intentional (keeping "10 kg" on one line). Stripping every U+00A0 can change meaning. Read the flags, decide case by case, then apply the cleaned copy the tool offers. The fourth is forgetting normalization: cleaning invisible characters does not merge composed and decomposed forms. Those need NFC, which is a separate step.

Related tools

Once your text is clean, the counting and analysis tools give reliable numbers. Use the Word Frequency & N-gram Analyzer to see which tokens dominate, and the Readability Scorer for Flesch and related scores. If a palindrome or anagram check keeps failing on text that looks correct, an invisible character is a likely cause, so inspect first, then try the Anagram & Palindrome Checker.

Frequently asked questions

Why does my text have more bytes than characters?

Because UTF-8 uses one to four bytes per codepoint. Only ASCII (U+0000 to U+007F) is one byte. Any accented letter, symbol, CJK character or emoji costs more, so "naïve" (5 codepoints) is 6 bytes and "😀" (1 codepoint) is 4 bytes.

How do I find a zero-width space I cannot see?

Paste the text into the inspector. Each codepoint is listed with its U+ code and name, so a U+200B ZERO WIDTH SPACE appears in the list even though it draws nothing on screen. The tool also flags it as suspect.

What is the difference between a codepoint and a character?

A codepoint is one number in the Unicode range. A "character" you see (a grapheme cluster) can be several codepoints, as with combining accents or emoji sequences. The family emoji is one grapheme but five codepoints.

Will cleaning invisible characters change how my text looks?

Usually not, since the flagged characters are invisible or interchangeable with a plain space. The exception is intentional formatting, such as a non-breaking space that keeps a number and its unit together. Check the flags before you accept the cleaned copy.

Does this send my text anywhere?

No. The analysis runs entirely in your browser, so nothing you paste leaves your device.