Emoji Unicode Cheatsheet - Emoji Encoding Reference
Emoji look fine on your screen until they break a MySQL column or get mangled in a JSON API. Organized by category, each emoji shows its codepoint and tips on surrogate pairs, ZWJ sequences and UTF-8 storage. Use it to size TEXT columns correctly, reason about why 👨👩👧 isn't a single codepoint, and handle emoji server-side without corruption. After reading you store and transmit emoji safely.
Typical Use Case
For developers building emoji pickers, rendering notifications, and filtering or de-duplicating emoji input. This sheet lists the Unicode code points and names of 48 high-frequency emoji: faces (from U+1F600), gestures (from U+1F44D), animals, food, sports and objects. The code points are the part that matters — an emoji occupies 4 bytes in UTF-8 and two code units in a JavaScript surrogate pair, so filtering, de-duplication and length calculation all require the exact code point. The English names (grinning face and friends) are the search keys that align with the Unicode standard.
Smileys & Emotion 10
😀 U+1F600😂 U+1F602😊 U+1F60A😍 U+1F60D😎 U+1F60E😭 U+1F62D😡 U+1F621👍 U+1F44D👎 U+1F44E👏 U+1F44FGestures 6
🙏 U+1F64F🤝 U+1F91D✌️ U+270C🤞 U+1F91E🤘 U+1F918👌 U+1F44CHearts 6
❤️ U+2764💔 U+1F494💕 U+1F495💖 U+1F496💗 U+1F497💘 U+1F498Animals 10
🐶 U+1F436🐱 U+1F431🐭 U+1F42D🐰 U+1F430🦊 U+1F98A🐻 U+1F43B🐼 U+1F43C🐨 U+1F428🐯 U+1F42F🦁 U+1F981Food 8
🍎 U+1F34E🍕 U+1F355🍔 U+1F354🍟 U+1F35F🌭 U+1F32D🍿 U+1F37F☕ U+2615🍺 U+1F37AActivities & Items 8
⚽ U+26BD🏀 U+1F3C0🎮 U+1F3AE🎵 U+1F3B5🎉 U+1F389🎁 U+1F381📱 U+1F4F1💻 U+1F4BBParameter matrix
| Parameter | Effect | Example |
|---|---|---|
code point U+XXXXX | the unique identifier of an emoji, used for regex filtering, dedupe and primary keys | thumbs up U+1F44D |
emoji block range | test whether a character is an emoji by range instead of enumerating one by one | U+1F600 grinning face |
English name | the standard-aligned search key for pickers, tag systems and cross-platform validation | U+1F3B5 musical note |
variation selector | note that some entries here (victory hand U+270C) carry a selector and take two code points | victory hand U+270C |
semantic category | group faces, gestures, animals, food and sports to lay out a picker by section | U+1F355 pizza |
Common pitfalls
SymptomIn JavaScript emoji.length returns 2 and truncating the string cuts the emoji in half.
CauseEmoji live outside the BMP and occupy two UTF-16 surrogate code units, and length counts code units.
FixIterate with [...str] or Array.from(str), or read codePointAt() and truncate by code point.
SymptomTwo emoji that look identical are treated as two different values.
CauseEmoji carrying a variation selector (victory hand U+270C) have one more code point, U+FE0F, than those without it.
FixNormalize before comparing or de-duplicating by stripping the U+FE0F variation selector.
SymptomA database column sized at 10 characters cannot hold a single full emoji sequence.
CauseOne emoji takes 4 bytes under utf8mb4, and in some engines varchar length is counted in characters but truncated by bytes.
FixUse utf8mb4 throughout and size emoji-bearing columns with enough headroom.
SymptomEmoji in notifications render as empty boxes on some platforms.
CauseThe target font or platform lacks a glyph for that code point, and a missing glyph becomes a tofu box.
FixStick to widely covered base emoji such as those in this face section, and keep a text fallback for critical notifications.
Troubleshooting
1Read an emoji code point and its code unit length
node -e "const s=process.argv[1];console.log([...s].map(c=>c.codePointAt(0).toString(16)))" "👍"A single value such as 1f44d means one code point; two values mean a surrogate pair or a variation selector.
2Test whether a string contains emoji-block characters
node -e "console.log(/[\u{1F300}-\u{1FAFF}]/u.test(process.argv[1]))" "hi 👍"true means it fell inside the emoji range; the u flag is what makes surrogate pairs work.
Command Examples
Inspecting emoji length, code point and surrogate pair
node -e "
const e = '\u{1F600}';
console.log('length', e.length, 'codePointAt', e.codePointAt(0).toString(16), 'charCodeAt', e.charCodeAt(0).toString(16));
console.log('fromCodePoint', String.fromCodePoint(0x1f600) === '\u{1F600}');
"A length of 2 reveals the surrogate pair. charCodeAt(0) returns the high surrogate 0xD83D; only codePointAt gives the real code point.
Output
length 2 codePointAt 1f600 charCodeAt(0) d83d fromCodePoint true
Why a variation-selector emoji compares unequal
node -e "
const a = '\u{1F600}', b = '\u{1F600}\u{FE0F}';
console.log(a === b, a.codePointAt(0) === b.codePointAt(0));
console.log([...b].map(c => c.codePointAt(0).toString(16)));
"The strings differ while their first code points match. For deduplication, compare code point sequences or strip variation selectors such as FE0F first.
Output
false true [ '1f600', 'fe0f' ]
Filtering emoji out of text with a code point range
node -e "
const re = /[\u{1F300}-\u{1FAFF}]/u;
const t = 'ship \u{1F680} done\u{1F600} ok';
console.log([...t].filter(c => re.test(c)).join(' '));
console.log('count', [...t].filter(c => re.test(c)).length);
"The u flag makes the range work on code points; without it the surrogate pairs get split. Spreading the string guarantees iteration by code point rather than by code unit.
Output
🚀 😀 count 2
Checking the UTF-8 byte length of each emoji
python -c "
for c in ['\U0001F600', '\U0001F44D', '\u2764']:
print(hex(ord(c)), len(c.encode('utf-8')))
"Supplementary-plane code points take four bytes while BMP symbols take three, so sizing every column at four wastes space and sizing at three overflows.
Output
0x1f600 4 0x1f44d 4 0x2764 3
Common Pitfalls
- Never treat an emoji length as a character count. Surrogate pairs pin length at 2 and naive truncation emits half a glyph; slice by visible width with Intl.Segmenter instead.
- Two emoji that look identical may differ in code point sequence, typically the U+FE0F variation selector. Normalize before deduplicating or your counts double.
- MySQL needs the utf8mb4 charset to store supplementary-plane code points; the older three-byte utf8 fails outright on U+1F600.
- Add the u flag to any code point range regex. Without it matching happens per code unit and the surrogate pair splits into two meaningless characters.
- Do not size a database column as one character per emoji: skin-tone modifiers and variation selectors can push a single grapheme past ten code units, and too narrow truncates silently.
Tips
- Emoji are 4-byte UTF-8; MySQL needs the utf8mb4 charset to store them.
- Emoji render differently across systems (iOS, Android, Windows each have their own font).
- In JavaScript use String.fromCodePoint(0x1F600) to produce an emoji.
- Some emoji are multiple Unicode combined (skin tone, gender) and may exceed length 2.
- Match emoji with \p{Emoji} or a dedicated emoji regex library.
FAQ
Why does an emoji have length 2 in JavaScript?
JS strings count UTF-16 code units, and U+1F600 sits outside the BMP so it needs a surrogate pair: high surrogate 0xD83D plus low surrogate 0xDE00 — exactly two units. To count what a reader perceives as one character, iterate code points (the spread operator) or use Intl.Segmenter. Truncating to a visible width requires Segmenter too, otherwise the pair gets split and you ship half a glyph.
Are U+2764 and U+2764 plus U+FE0F the same emoji?
They are different code point sequences even though they usually look identical. U+2764 is the heart itself; U+FE0F is the variation selector asking for the colour emoji presentation rather than the monochrome text form. Several entries in the table carry it. The consequence: the two strings are unequal for deduplication while their first code points match, so emoji validation must iterate code points instead of treating a raw code point value as a unique key.
Why do entries like the hot beverage (U+2615) and soccer ball (U+26BD) sit so far from the others?
Because they occupy a different block. Most faces live in the supplementary planes between U+1F300 and U+1FAFF and take four UTF-8 bytes, while U+2615 and U+26BD live in the BMP miscellaneous symbols block and take three bytes. They were originally defined as text symbols with emoji presentation, so they too often need U+FE0F to render in colour. A range filter that only covers the supplementary planes will miss them, and you cannot assume four bytes per glyph.
What goes wrong when an emoji count sets the database column width?
Silent truncation, or outright write failures. One glyph the reader sees as single may be a surrogate pair (two code units) plus a skin-tone modifier and a variation selector, easily a dozen code units; with VARCHAR(10) defined by character count the UTF-8 byte cost multiplies it again. The safe route is a utf8mb4 column sized with headroom for the worst case, or a TEXT / JSON column with validation in application code, rather than relying on database length semantics.
How do I count the emoji in a string quickly?
Iterate by code point and test each one against a regular expression instead of dividing the length. Spreading the string into a code point sequence and matching each element against an emoji range regex with the u flag yields the real count. That approach sidesteps the inflated length caused by surrogate pairs, and it is a required step before truncating notification text.
Official References
Each command links to its official documentation below, so you can verify the latest usage and read deeper.
Maintained by LaoHand
Publicly updated on Jul 21, 2026, continuously proofread against official docs.
Contact Us
Wrong command or description? Send us corrections, business inquiries or product feedback by email.
Contact Us