How Emoji Work: Unicode Code Points, Skin Tones, and ZWJ Sequences
An emoji is not just a tiny picture; it is a "character" built on Unicode, the worldwide standard for text. This article explains the code points behind emoji, surrogate pairs, skin-tone modifiers, the ZWJ mechanism that joins several emoji into one, why they look different across environments, and why character counts can be thrown off.
The emoji you casually use on your phone, like 😀 or 👍, are not images at all. Internally they are treated exactly like letters or Chinese characters, that is, as "characters." The foundation for this is Unicode, the system that assigns a number to every character in the world. This article explains, step by step, what numbers make up an emoji, how skin tones and family emoji are assembled, and why phenomena such as "it should be one character, but the count went up" actually happen.
What Is an Emoji: A Character Built on Unicode
An emoji looks like a small picture, but inside a computer it is stored and processed as a kind of character. Every character in the world (letters, Chinese characters, Hangul, symbols, and so on) is assigned a unique number, and that numbering system is Unicode. Because emoji are officially registered in Unicode, you can use them anywhere text is allowed, such as email, social media, and file names.
In other words, an emoji is not a pasted image file; it is simply an instruction that says "please display the character with this number." The receiving device draws and shows the picture that corresponds to that number. That is exactly why the same emoji can look slightly different on iPhone, Android, and Windows. If you browse the list in the Emoji Picker, you will likely be surprised by just how many are registered.
Code Points and Their Positions
The number Unicode assigns to each character is called a code point. A code point is usually written as "U+" followed by a hexadecimal number. For example, the grinning face 😀 is U+1F600, and the thumbs-up 👍 is U+1F44D. This is the very same mechanism by which the letter "A" is U+0041.
To hold an enormous number of characters, Unicode divides the code-point range into several blocks called planes. Most basic characters fit in the Basic Multilingual Plane (BMP), U+0000 to U+FFFF, but most emoji sit beyond it, around U+1F300 to U+1FAFF in a supplementary plane. The fact that emoji live in this high-numbered region is also related to the "count mismatch" explained later.
When you want to find out which code point an emoji or symbol is, paste the character into the Unicode Inspector, and you can check each U+ number one by one. This is also where you discover that a familiar emoji is actually made of a combination of several numbers.
Surrogate Pairs and Byte Counts
Why are emoji numbers "heavier" than ordinary characters? The key is a mechanism called the surrogate pair. It is used in UTF-16, the encoding used by JavaScript and others, to represent large code points beyond the BMP.
In UTF-16, a single unit (16 bits) can only represent the range U+0000 to U+FFFF. So a character beyond that range, like 😀 (U+1F600), is represented by combining two units into one character. This two-in-one pair is the surrogate pair. As a result, even though it looks like one character, it is handled internally as two units of data.
- "A" (U+0041): representable in one unit; a program sees length 1.
- "😀" (U+1F600): a surrogate pair, two units; some programs see length 2.
This gap of "one character to a human, two units to a machine" is the real cause of the character-counting pitfall. When a form's input limit or a social-media character limit suddenly jumps the moment you add an emoji, the surrogate pair is often the reason.
Skin-Tone Modifiers and Variations
Some emoji let you choose the skin color of the same hand or face. You have probably seen variations such as 👍🏻👍🏽👍🏿 in different colors, not just 👍. These are not separate emoji prepared for each color; they are produced by attaching a dedicated skin-tone character (a skin-tone modifier) after the base emoji.
There are five skin-tone modifiers, U+1F3FB to U+1F3FF, corresponding to five shades of skin tone. For example, if you place a medium skin-tone modifier (U+1F3FD) right after 👍 (U+1F44D), the system combines the two and draws them as a single "medium-tone thumbs-up." This is another case where several code points combine into one appearance.
In addition, emoji have a character called a variation selector that switches how something is displayed. The same symbol may be drawn as a "colorful emoji" when followed by U+FE0F, and as a "monochrome symbol" when not. It is not unusual for two things to look almost identical yet have different internal code-point sequences. If you break down an emoji you are curious about in the Unicode Inspector, you can notice these hidden modifiers.
ZWJ Sequences: Joining Emoji Together
How are family emoji like 👨👩👧👦 or profession emoji like 👩💻 made? These are sequences in which multiple emoji are joined together by a "glue" called the ZWJ (Zero Width Joiner, U+200D).
The ZWJ is a special zero-width character that displays nothing on its own. For example, if you send the sequence "man (👨) + ZWJ + woman (👩) + ZWJ + girl (👧) + ZWJ + boy (👦)," a device that supports it bundles them together and shows a single "family" picture. Likewise, "woman (👩) + ZWJ + laptop (💻)" becomes a "woman technologist."
The important point is that in environments that do not support ZWJ sequences, the joined emoji are shown separately. This is why a family emoji may look like "just several people side by side" on some devices. Even when it looks like one picture, internally it is a long run of multiple emoji and ZWJs, so the character count is larger than it appears.
Cross-Platform Differences and Character Counting
As we have seen, an emoji is not always "one number equals one picture." Because mechanisms such as surrogate pairs, skin-tone modifiers, variation selectors, and ZWJ sequences combine, what looks like one character is often made of multiple code points and multiple units internally. This is the biggest reason character counting becomes difficult.
| Emoji | Internal composition | Example of how it is counted |
|---|---|---|
| A | 1 code point | 1 character |
| 😀 | 1 code point (2 units as a surrogate pair) | sometimes counted as 2 |
| 👍🏽 | emoji + skin-tone modifier | sometimes counted as 4 |
| 👨👩👧👦 | 4 emoji + 3 ZWJs | sometimes counted as 11 |
So when you use emoji under a "up to N characters" limit on social media or in a form, you may hit the cap far sooner than expected. This is not a bug; it is an inevitable consequence of emoji being built from combinations of characters. Conversely, once you understand the internal structure, you can avoid the confusion of "the count just doesn't add up."
Also, even for the same code-point sequence, how it is drawn as a picture is left to the device maker and the font. That is exactly why the same emoji can look like a different expression on each platform, and why a new emoji may appear as "□" or "?" on an older device. When you want to confirm exactly which numbers are combined, break it down in the Unicode Inspector, and when you want to find an emoji to type, use the Emoji Picker to understand the mechanism with your own eyes.
Please note that this article is intended to provide general information. The Unicode standard and platform support are updated continuously, and the available emoji and their display vary by environment. For precise specifications, please check the latest official information, such as materials from the Unicode Consortium.
FAQ
Is an emoji an image or a character?
An emoji is a character, not an image. It is officially registered in Unicode, the system that assigns a number to every character in the world, and internally it is handled as an instruction to "display the character with this number." Because the receiving device draws the picture for that number, the same emoji can look different from device to device.
What is a code point?
A code point is the unique number Unicode assigns to each character. It is usually written as "U+" followed by a hexadecimal number; for example, the grinning face 😀 is U+1F600. This is the same mechanism by which the letter "A" is U+0041, and emoji are numbered the same way.
Why does the character count go up when I add an emoji?
Many emoji are handled internally as two units via a surrogate pair, and when skin-tone modifiers or ZWJ sequences are added, an emoji becomes a combination of several code points. So even though it looks like one character, a machine may see several, which can make you reach a character limit sooner.
How are family and skin-tone emoji made?
Skin-tone emoji are made by adding a dedicated skin-tone modifier (U+1F3FB to U+1F3FF) after the base emoji. Family emoji are sequences in which several emoji are joined by a ZWJ (Zero Width Joiner, U+200D). On supporting devices they combine into one picture, while on unsupported devices they appear separately.
When I input or analyze emoji, is the data sent to a server?
WAZA TOOLS' Emoji Picker and Unicode Inspector run entirely in your browser, so the characters you enter and the emoji you copy are never sent to or stored on a server. They work on smartphones too, and you can use them as many times as you like, for free.