An emoji that looks like one character can be reported as 1, 2, 4, 7 or 11, because software measures "characters" in different units. Counted as a visible character, every emoji is 1. Counted in Unicode code points, UTF-16 code units or UTF-8 bytes, the same emoji can be several, because many emoji are built from a sequence of smaller pieces. Each number is a correct answer to a different question.

Five emoji, four ways of counting

Emoji Name Visible characters Code points UTF-16 units UTF-8 bytes
πŸ™‚ slightly smiling face 1 1 2 4
πŸ‘πŸ½ thumbs up, medium skin tone 1 2 4 8
πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ family: man, woman, girl, boy 1 7 11 25
πŸ‡΅πŸ‡° flag: Pakistan 1 2 4 8
1️⃣ keycap: 1 1 3 3 7

The four units mean different things:

  • Visible character. What a reader sees as one symbol. Unicode calls this a grapheme cluster, and its text segmentation annex describes it as a "user-perceived character". The same annex says that each emoji sequence in the set recommended for general interchange is a single grapheme cluster.
  • Code point. One numbered entry in Unicode, written like U+1F642.
  • UTF-16 code unit. A 16-bit value. A code point up to U+FFFF fits in one unit. Anything higher needs two, known as a surrogate pair, and most emoji sit above U+FFFF.
  • UTF-8 byte. UTF-8 stores a code point in one to four bytes, and always four for a code point above U+FFFF.

That explains the simplest row. πŸ™‚ is a single code point, U+1F642, but it lies above U+FFFF, so it takes 2 UTF-16 units and 4 bytes. It is why JavaScript reports the length of "πŸ™‚" as 2.

What the longer emoji are made of

The other four rows are sequences of code points that a font draws as one picture.

Emoji Code points, in order
πŸ‘πŸ½ U+1F44D thumbs up sign, U+1F3FD emoji modifier Fitzpatrick type-4
πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ U+1F468 man, U+200D zero width joiner, U+1F469 woman, U+200D, U+1F467 girl, U+200D, U+1F466 boy
πŸ‡΅πŸ‡° U+1F1F5 regional indicator symbol letter P, U+1F1F0 regional indicator symbol letter K
1️⃣ U+0031 digit one, U+FE0F variation selector-16, U+20E3 combining enclosing keycap

Skin tone modifiers

Unicode has five skin tone modifiers, U+1F3FB to U+1F3FF. A modifier changes the emoji directly before it, and the Unicode emoji standard requires it to follow the base emoji immediately. Every modifier is above U+FFFF, so it adds 1 code point, 2 UTF-16 units and 4 bytes. A plain πŸ‘ measures 1, 2 and 4 in those three units; πŸ‘πŸ½ measures 2, 4 and 8.

On a system that cannot draw the combination, the fallback described in the Unicode emoji standard is the unmodified emoji followed by a separate color swatch. The text has not changed, only the way it is drawn.

Zero-width joiner sequences

U+200D ZERO WIDTH JOINER, usually shortened to ZWJ, is an invisible code point that asks the display to merge its neighbors into one picture. The family emoji is four people held together by three joiners, which gives 7 code points. The other columns follow from that:

  • UTF-16: four people at 2 units each, plus three joiners at 1 unit each, is 11.
  • UTF-8: four people at 4 bytes each, plus three joiners at 3 bytes each, is 25.

The Unicode emoji standard says the joiner indicates "that a single glyph should be presented if available". When a device has no such picture, it ignores the joiners and shows the people side by side. The same message can therefore look like one emoji on one phone and four on another, while every count stays the same: counts are worked out from the code points, not from the font.

Flags

A country flag is a pair of regional indicator letters. There are 26 of them, U+1F1E6 to U+1F1FF, one for each letter from A to Z, and the pair spells a region code: P and K for Pakistan. Both letters are above U+FFFF, so a flag is 2 code points, 4 UTF-16 units and 8 bytes.

One regional indicator on its own is not a flag. Unicode's grouping rules pair the letters from the left, so three in a row count as one flag followed by one leftover letter.

The flags of England, Scotland and Wales use a different mechanism: a black flag, U+1F3F4, followed by invisible tag characters and a closing tag. The flag of England comes to 7 code points, 14 UTF-16 units and 28 bytes, and is still one visible character.

Variation selector-16 and keycaps

U+FE0F VARIATION SELECTOR-16 is another invisible code point. It requests the emoji style for a character that can also be drawn as plain text. The red heart is a good example. ❀️ is U+2764 followed by U+FE0F: 2 code points, 2 UTF-16 units and 6 bytes. U+2764 without the selector is 1 code point, 1 unit and 3 bytes, and some systems draw it as a flat text symbol. Two hearts that look alike can differ by one code point.

A keycap uses the selector as well: a digit, then U+FE0F, then U+20E3 COMBINING ENCLOSING KEYCAP. All three are below U+FFFF, so the keycap is 3 code points and also 3 UTF-16 units, and its bytes are 1 + 3 + 3 = 7. It is the only row in the first table where the code point and UTF-16 columns agree.

Which number each system reports

Unit Family emoji πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘¦ Where you meet it
Visible characters 1 The main count on this site; count on a Swift string
Code points 7 Iterating over a JavaScript string, as in [...text].length
UTF-16 code units 11 JavaScript .length; the HTML maxlength attribute; SMS sent as Unicode
UTF-8 bytes 25 File sizes; fields whose limit is set in bytes
X weighted length 2 Posts on X

The programming rows are documented. MDN states that length is measured in UTF-16 code units, and shows the string iterator as the way to count whole code points instead. The HTML Standard measures maxlength the same way as length. Swift's documentation says that each Character is an extended grapheme cluster and that count returns the number of them.

Several consumer products do not document their unit. Instagram, LinkedIn and YouTube (for video titles) give their limits in "characters" and say nothing about how an emoji is counted. For those, the limit presets on this site count visible characters and label the result as approximate. The dependable test is to paste an emoji into the real field and watch that field's own counter.

X counts 2, SMS counts UTF-16 units

X publishes its rule: every emoji counts as 2, whatever it is made of. X's own documentation lists a single emoji, an emoji with a skin tone and the four-person family as 2 each, and notes that joiners do not add to the count. The X preset in the Character Counter applies that rule.

SMS is different again. An emoji forces the whole message into the Unicode encoding, where capacity is counted in 16-bit units and a single message holds 70 of them. πŸ™‚ uses 2 of the 70, πŸ‘πŸ½ uses 4 and the family uses 11. The guide to emoji in text messages covers the details, and the SMS Character Counter shows the split for your own message.

When two counters disagree

If two tools give different numbers for the same emoji, check these in order:

  1. They count different units. Start here: find out which row of the table above each tool reports.
  2. The text is not the same. A heart with and without U+FE0F can look the same and still differs by one code point, and text from different sources may or may not include the selector.
  3. The software uses different Unicode data. Grouping code points into visible characters depends on rules that are revised with new Unicode versions (the current one is 18.0). This site uses the segmenter built into your browser, so an old browser can group an unusual sequence differently from a current one.

Which number to use

  • A limit a person reads, such as a bio or form field that only says "characters": start from visible characters, then confirm in the real field if the text has many emoji.
  • A post on X: use the weighted count, 2 per emoji.
  • A text message: use an SMS counter. An ordinary character count cannot tell you how many parts the message will be split into.
  • An HTML form or JavaScript validation: UTF-16 code units, unless the code says otherwise. The guide to JavaScript string length shows how to get each number.
  • Storage: bytes or code points, depending on the system. See UTF-8 bytes vs characters.

The Character Counter shows visible characters as its main figure and lists code points, UTF-16 code units and UTF-8 bytes under Advanced statistics, so you can read off whichever unit the destination uses.