User Rating 0.0 β˜…β˜…β˜…β˜…β˜…
Total Usage 0 times
Supports Unicode, emoji, combining marks, and multi-line text.
Is this tool helpful?

Your feedback helps us improve.

β˜… β˜… β˜… β˜… β˜…

About

JavaScript's String.length returns UTF-16 code units, not visible characters. A single emoji like πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ reports 11 from .length but renders as 1 grapheme cluster. Database column limits, SMS segments (160 GSM-7 characters or 70 UCS-2), and API payload caps operate on different length definitions. Confusing code units with bytes or graphemes causes silent data truncation, broken emoji rendering, and failed validation. This tool computes all five canonical string metrics simultaneously: UTF-16 code units, Unicode code points, grapheme clusters, UTF-8 byte length, and word/line counts.

The grapheme segmentation uses the Intl.Segmenter API (UAX #29) when available, which correctly handles zero-width joiners, combining marks, and regional indicator sequences. UTF-8 byte count is derived via Blob constructor, matching what your server receives over HTTP. Note: results assume well-formed input. Lone surrogates (unpaired UTF-16 halves) produce implementation-defined byte counts.

string length character count byte count word count unicode grapheme clusters text analysis

Formulas

Five distinct length metrics are computed from an input string S:

Lutf16 = S.length

Returns the number of UTF-16 code units. Surrogate pairs (code points above U+FFFF) count as 2.

Lcp = [...S].length

The spread operator iterates by Unicode code point, correctly counting astral plane characters (emoji, rare CJK) as 1 each.

Lgrapheme = Intl.Segmenter(S, {granularity: "grapheme"})

UAX #29 segmentation. A grapheme cluster is the smallest user-perceived character unit. Emoji sequences joined with Zero-Width Joiners (U+200D) and characters with combining marks each count as 1.

Lbytes = new Blob([S]).size

UTF-8 encoded byte length. ASCII characters use 1 byte. Most Latin/Cyrillic use 2. CJK and common symbols use 3. Emoji and astral characters use 4.

Lwords = S.split(/\s+/).filter(Boolean).length

Where Lutf16 = UTF-16 code unit count, Lcp = Unicode code point count, Lgrapheme = grapheme cluster count (visual characters), Lbytes = UTF-8 byte size, Lwords = whitespace-delimited token count.

Reference Data

Character / SequenceVisualUTF-16 UnitsCode PointsGraphemesUTF-8 Bytes
Latin letter AA1111
Euro sign€1113
CJK ideograph (water)ζ°΄1113
Emoji (grinning face)πŸ˜€2114
Emoji (flag US)πŸ‡ΊπŸ‡Έ4218
Family emoji (ZWJ)πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦117125
e + combining acuteΓ© (2 CP)2213
Precomposed éé (1 CP)1112
Hindi syllable ΰ€•ΰ₯ΰ€·ΰ€Ώΰ€•ΰ₯ΰ€·ΰ€Ώ44112
Korean syllable ν•œν•œ1113
Musical symbol π„žπ„ž2114
Newline (LF)\n1111
Tab\t1111
Empty string(none)0000
Space(space)1111
Skin-toned emoji πŸ‘‹πŸ½πŸ‘‹πŸ½4218
Keycap sequence 1️⃣1️⃣3317
Zalgo text (10 combiners)αΊ•Μ΄Μ’Μ›Μ«Μ€ΜˆΜΜ‘Μ‹ΜƒΜˆ1111125

Frequently Asked Questions

JavaScript strings use UTF-16 encoding internally. Characters with code points above U+FFFF (the Basic Multilingual Plane) require a surrogate pair - two 16-bit code units. The .length property counts code units, not code points. For example, πŸ˜€ is U+1F600, which encodes as the pair U+D83D U+DE00, giving a .length of 2. Use [...str].length or the code point count from this tool to get the correct count of 1.
A code point is a single entry in the Unicode table (e.g., U+0041 for 'A'). A grapheme cluster is what a human perceives as one character. The family emoji πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ consists of 7 code points (4 person emoji + 3 zero-width joiners) but renders as 1 grapheme cluster. Similarly, "Γ©" can be composed of 2 code points (e + combining acute accent) but is 1 grapheme. The Intl.Segmenter API implements UAX #29 to segment correctly.
It depends on the column type. MySQL's VARCHAR(n) in utf8mb4 counts characters (code points). PostgreSQL's VARCHAR(n) also counts characters. However, MySQL's VARBINARY(n) counts bytes. For HTTP Content-Length headers and file size calculations, use the UTF-8 byte count. For SMS messages, use UTF-16 code units: a GSM-7 message allows 160 characters, but if any character requires UCS-2 encoding, the limit drops to 70 UTF-16 code units.
Intl.Segmenter follows Unicode Standard Annex #29, but the supported Unicode version varies by browser engine. Newer emoji sequences (e.g., added in Unicode 15.1) may not be recognized as single grapheme clusters by older browsers, causing them to be split into multiple segments. This tool falls back to a regex-based approximation if Intl.Segmenter is unavailable, which handles most ZWJ sequences and regional indicators but may miss edge cases in newest emoji.
Unicode defines multiple ways to encode the same visual character. "Γ©" in NFC (composed) is 1 code point U+00E9. In NFD (decomposed) it is 2 code points: U+0065 (e) + U+0301 (combining acute). This means the same visual text can have different .length values depending on normalization form. This tool measures the string exactly as provided. Use str.normalize('NFC') before measuring if you need canonical comparison. The grapheme cluster count remains the same regardless of normalization.
Yes. Lines are counted by splitting on the newline character \n. A CRLF sequence (\r\n) contains one \n, so it counts as one line break. However, note that \r\n contributes 2 to UTF-16 length and 2 bytes in UTF-8, while a bare \n contributes 1 to each. The word count treats both \r and \n as whitespace, so word counts are unaffected by line ending style.