How emoji are encoded

An emoji looks like one image, but under the hood it can be anything from a single code point to a chain of several joined together. Understanding the encoding demystifies why some emoji behave strangely in code.

Single-code-point emoji

Many emoji are one code point — 🔥 is U+1F525, ⭐ is U+2B50. Simple to store and handle.

Emoji sequences

Others are built from several code points:

  • Skin tones — a base emoji plus a modifier (👍 + 🏽 = 👍🏽).
  • ZWJ sequences — multiple emoji glued with a Zero Width Joiner (👨 + ZWJ + 💻 = 👨‍💻).
  • Flags — two “regional indicator” letters (🇺 + 🇸 = 🇺🇸).
  • Keycaps — a digit + variation selector + combining enclosing keycap (1️⃣).

Why it matters for developers

Because one visible emoji can be many code points, naive code that counts characters, truncates strings, or reverses text can split an emoji in half and produce garbage. Use grapheme-aware tools (like Intl.Segmenter) when handling user text.

Want the icon, not the emoji?

For UIs, a clean vector icon beats an emoji — search 311,000+ free icons.

Browse icons →

Frequently asked questions

Is every emoji one character?

No — many are sequences of multiple code points (skin tones, professions, flags), even though they display as one glyph.

Why does slicing a string break emoji?

Because an emoji may be several code units; cutting between them splits the sequence. Use grapheme-aware segmentation.