Inspect Unicode · browser-local
Grapheme Counter
Count graphemes — the characters a person sees — using Unicode text segmentation, and compare them to code points and UTF-16 units so combined and joined sequences are clear.
- Index state
- eligible
- Reviewed
- 2026-08-24
- Input limit
- 5,000 graphemes
Grapheme Counter
Good fit
Use this tool when
- You need the human-perceived character count.
- Your text has emoji, accents, or joined sequences.
- You want to see how many code points collapse into one grapheme.
Keep the original
Avoid it when
- You need bytes for a size budget.
- You need words or lines rather than characters.
- The destination counts code units, not graphemes.
Reviewed truth vectors
Examples that expose the edge cases
👨👩👧👦1 grapheme · 7 code pointsA family emoji is one grapheme built from many code points.
café4 graphemes · 4 code pointsPrecomposed é is a single code point here.
café4 graphemes · 5 code pointsA combining accent adds a code point but not a grapheme.
Transparent implementation
How it works
- 01
Segment the text into graphemes with Intl.Segmenter (UAX #29).
- 02
Count code points and UTF-16 code units separately.
- 03
Show the difference as combined or joined units.
Known limitations
What the result cannot promise
Segmentation follows the runtime's Unicode data version.
Some fonts render sequences that segmentation still counts as separate graphemes.
It does not report bytes or words.
Questions before copying
Frequently asked questions
Why is a family emoji one grapheme?
It is a sequence of emoji joined by zero-width joiners that Unicode segmentation treats as a single user-perceived character.
What is the combining count?
It is the number of code points beyond the grapheme count, which come from combining marks or joiners.
Does it match String length?
Not usually. String length counts UTF-16 units, which is shown separately from graphemes.
Experience, expertise & trust
How we verify this tool
Automated evidence
- Tool-contract & coverage suite30 deterministic cases
tests/tools-30.test.mjs mirrors the ToolRunner dispatch and asserts every registered engineId returns the contracted output shape, plus a coverage guard so no tool silently drops characters.
Run in: node --test after a production build (vinext build) - Rendered-HTML suite12 deterministic cases
tests/rendered-html.test.mjs renders the deployed server bundle and asserts the Unicode-version manifest and each wave's tool markup are present in the server-rendered HTML.
Run in: node --test against the built dist/server bundle - Unicode inspection suite11 deterministic cases
tests/unicode-inspection.test.mjs verifies grapheme/code-point/byte counting and hidden-control detection using explicit \u escapes for combining and bidirectional characters.
Run in: node --test against the runtime's Unicode data - Compatibility risk suite13 deterministic cases
tests/compatibility.test.mjs checks that bidirectional controls, invisible characters, mixed scripts, and NFKC-changing input raise the documented risk status, and that safe-text stripping preserves ordinary content.
Run in: node --test, deterministic analyzer
Standards this tool follows
- UTS #39: Unicode Security Mechanisms
Confusable and mixed-script detection methodology.
- UAX #9: Unicode Bidirectional Algorithm
Bidirectional control characters flagged during inspection.
- UAX #15: Unicode Normalization Forms
NFC/NFKC normalization comparisons.
- RFC 3629: UTF-8
Byte-length counting for the UTF-8 encoding.