Grapheme clusters explained
Ask a user how many characters are in “👍🏽” and they'll say one. Ask a computer and it might say four. A grapheme cluster is the human answer — the unit you usually want when handling text.
Three different “lengths”
| Measure | 👍🏽 counts as |
|---|---|
| Bytes (UTF-8) | 8 |
| UTF-16 code units (JS .length) | 4 |
| Code points | 2 |
| Grapheme clusters (what users see) | 1 |
Why it matters
Character counters, truncation (“…” after N chars), cursor movement, and reversing text all break if they use bytes or code units. A skin-toned emoji or a flag can be split into nonsense. Grapheme-aware logic keeps user-perceived characters intact.
The modern tool
const seg = new Intl.Segmenter('en', { granularity: 'grapheme' });
[...seg.segment('👍🏽')].length // 1
Intl.Segmenter (built into modern browsers and Node) splits text into real graphemes so counting and slicing match what users expect.
Frequently asked questions
What is a grapheme cluster?
The smallest unit a reader perceives as one character — which may be several code points (e.g. an emoji with a skin tone).
How do I count characters the way users do?
Use grapheme segmentation (e.g. Intl.Segmenter) rather than .length or byte counts.