String / Unicode Inspector
Break any string into per-character code points, categories, byte lengths and escapes — entirely on this device.
Grapheme = what reads as one character · code point = one Unicode scalar · then its UTF-16 and UTF-8 lengths.
The per-character table appears here when you paste text.
The JSON report appears here after you paste text.
Press ? for shortcuts
Do it offline:$ uni identify 'café'
How to use it
- Paste or type text; your last input and any shared permalink are restored, and large pastes are measured off the main thread.
- Read the four totals on top — grapheme, code point, UTF-16 unit and UTF-8 byte — each copyable on its own.
- Open any grapheme cluster to see its code points, categories, both lengths and four escapes.
- Copy one cell or the whole report as JSON, or use the command line past the in-browser limit.
Paste any text and read it one character at a time. This inspector expands every grapheme cluster into its code points and reports four separate lengths — grapheme count, code point count, UTF-16 code units and UTF-8 bytes — beside each character's general category, hex value and escape forms. The whole breakdown is computed in this tab.
How it works
A string can be measured four ways at once. In é😀 a reader sees two things, so the grapheme count is 2; those clusters hold three code points — the letter e, the combining acute accent U+0301, and the face U+1F600. UTF-16 needs four code units because U+1F600 takes a surrogate pair; UTF-8 needs seven bytes. Cluster boundaries follow UAX #29.
That é is why the numbers can surprise you. Written as e followed by U+0301 it is two code points and the NFC line reads no; the precomposed é (U+00E9) is one code point, already in Normalization Form C. This page only reports NFC status — converting between the forms is a dedicated normalization tool's job.
Each code point carries a two-letter general category — Lu for a capital, Mn for the accent, So for a symbol — from the classes in UAX #44. Character names and compatibility folding such as NFKC stay off this page on purpose.
Examples
Hi!graphemes 3 · code points 3 · UTF-16 units 3 · UTF-8 bytes 3
NFC: yes
grapheme 1 "H" (1 code point)
U+0048 H Uppercase Letter (Lu) UTF-16 1 UTF-8 1 \u{48}
grapheme 2 "i" (1 code point)
U+0069 i Lowercase Letter (Ll) UTF-16 1 UTF-8 1 \u{69}
grapheme 3 "!" (1 code point)
U+0021 ! Other Punctuation (Po) UTF-16 1 UTF-8 1 \u{21}Plain ASCII is the calm case: all four totals read three, one byte per code point.
é😀graphemes 2 · code points 3 · UTF-16 units 4 · UTF-8 bytes 7
NFC: no
grapheme 1 "é" (2 code points)
U+0065 e Lowercase Letter (Ll) UTF-16 1 UTF-8 1 \u{65}
U+0301 ́ Nonspacing Mark (Mn) UTF-16 1 UTF-8 2 \u{301}
grapheme 2 "😀" (1 code point)
U+1F600 😀 Other Symbol (So) UTF-16 2 UTF-8 4 \u{1F600}One grapheme, two code points: the accent U+0301 sits on the e, so NFC reads no; the face is one code point across two UTF-16 units and four bytes.
👍🏽graphemes 1 · code points 2 · UTF-16 units 4 · UTF-8 bytes 8
NFC: yes
grapheme 1 "👍🏽" (2 code points)
U+1F44D 👍 Other Symbol (So) UTF-16 2 UTF-8 4 \u{1F44D}
U+1F3FD 🏽 Modifier Symbol (Sk) UTF-16 2 UTF-8 4 \u{1F3FD}The thumbs-up and the skin-tone modifier are two astral code points the segmenter joins into one grapheme — eight UTF-8 bytes in all.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
Astral characters travel as surrogate pairs
Any code point above U+FFFF becomes two UTF-16 units — a surrogate pair — so the grinning face U+1F600 is one code point but four UTF-8 bytes.
A combining accent is a character of its own
The accented é can be one code point U+00E9 or the two code points e and U+0301. Both look identical, yet only the second reports NFC as no — a common reason a search or a password check fails on text read as the same.
Emoji families, flags and skin tones are one grapheme
A zero-width joiner U+200D fuses several faces into one family; two regional indicators become one flag; a skin-tone modifier attaches to the emoji before it.
An unpaired surrogate is shown, not dropped
A surrogate with no partner is not valid text, but the row keeps its code point, shows U+FFFD, and counts three UTF-8 bytes.
Invisible characters are listed plainly, not judged
Control and format characters — tabs, newlines, the byte-order mark, zero-width spaces — are counted and shown through a labelled stand-in. Whether any of them are dangerous is the Invisible Character Detector's question.
Common errors
Input is larger than the 1 MB limit for this tool. For bigger inputs use the CLI: uni identify < input.txt- The whole input is declined, never partly measured — a partial read would misreport every total. arp242/uni inspects any size locally, and nothing is uploaded.
This input contains an unpaired surrogate code unit. It is shown as the replacement character U+FFFD (�) and counts as 3 UTF-8 bytes.- A lone surrogate usually comes from a string sliced through the middle of an emoji. The note says it is present and how it was counted, without hiding or rejecting it.
Showing the first 20000 of 20001 code points in the table below — the four totals above still cover the entire input.- Only the table is capped, so a long paste never freezes the page; the four totals still cover everything, and the JSON report has the rest.
FAQ
What is the difference between a grapheme, a character and a code point?
A grapheme is what a reader sees as one character, like é or a flag. A code point is one entry in the table, such as U+0065; one grapheme can hold several, so the two counts often disagree.
Why do two strings that look identical count differently?
Usually one is composed and the other decomposed. The letter é can be the single code point U+00E9 or the pair e plus U+0301; both render the same, but the second is one code point and one byte longer. The NFC line flags it.
Why does one emoji count as two code points and four bytes?
Many emoji are astral characters that need four UTF-8 bytes, and a skin tone or joiner adds its own code point. The count is the honest size a database column must hold.
Does anything I paste here leave my browser?
No. Segmentation, counting and the escape forms all run in this tab, with no request to any server and no account. The text is often a token or private data, so an input that looks credential-shaped is never stored between visits.
Keyboard shortcuts
- ⌘/Ctrl + Enter
- Measure the current text again immediately.
- ⌘/Ctrl + S
- Save the breakdown as a .json file, not the web page.
- ⌘/Ctrl + C
- With nothing selected, copy the JSON breakdown; a selection copies itself.
- ⌘/Ctrl + Shift + C
- Copy the JSON breakdown whether or not anything is selected.
- t
- Step to the next theme (idle while a field has focus).
- ? or ⌘/Ctrl + /
- Open the shortcut help panel.
- Esc
- Dismiss the top overlay and return focus to its opener.