Emoji picker
Copy and paste emojis easily and get the unicode and code points value of each emoji.
Modern Emoji Picker & Unicode Character Inspector: UTF-8 Encoding, Grapheme Clusters, and Zero-Width Joiner Sequences
1. Quick Overview & Core Advantages
The Modern Emoji Picker and Unicode Character Inspector is an in-browser developer utility designed for searching, inspecting, previewing, and copying standard Unicode emojis and typographic glyphs. Standardized by the Unicode Consortium under technical standards UTS #51 (Unicode Emoji) and UAX #29 (Unicode Text Segmentation), emojis represent one of the most structurally complex encoding subsystems in modern software engineering.
What appears on a smartphone screen as a single visual characterβsuch as a female astronaut with a medium-dark skin tone (π©πΎβπ)βis frequently a composite sequence of multiple distinct Unicode code points bound together by invisible Zero-Width Joiners (ZWJ) and modifier characters.
Core Architectural Advantages
- 100% In-Browser Instant Client-Side Rendering: Searches, filters, and Unicode code point decompositions happen natively within the browserβs JavaScript V8/SpiderMonkey engine. No network latency, third-party font server lookups, or remote query overhead.
- Deep Unicode Forensics: Beyond simple clipboard copy-pasting, the tool exposes underlying hexadecimal code points (
U+1F600), UTF-8 byte representations, UTF-16 surrogate pairs (\uD83D\uDE00), HTML decimal/hexadecimal entities, and CSS escape sequences. - Grapheme Cluster Segmentation Compliance: Leverages modern ECMAScript internationalization APIs (
Intl.Segmenter) to accurately calculate the true visual length of complex compound emojis, preventing string truncation bugs in databases and UI inputs.
2. Step-by-Step Custom Configuration & Usage Guide
Handling emojis reliably across software stacks requires converting between visual glyphs, code points, surrogate pairs, and UTF-8 byte arrays.
Step 1: Searching and Filtering by Unicode Metadata
The picker provides fuzzy search indexing across official CLDR (Common Locale Data Repository) keywords, annotations, and category groupings (Smileys & Emotion, People & Body, Animals & Nature, Food & Drink, Travel & Places, Activities, Objects, Symbols, Flags).
Step 2: Extracting Code Points & Surrogate Pairs in TypeScript
In JavaScript, characters outside the Basic Multilingual Plane (BMP, code points above U+FFFF) are represented as two 16-bit code units called surrogate pairs:
export interface EmojiForensicData {
glyph: string;
codePoints: string[];
utf16Surrogates: string;
utf8HexBytes: string;
htmlEntity: string;
visualGraphemeCount: number;
}
export function inspectEmoji(glyph: string): EmojiForensicData {
// 1. Extract array of hexadecimal Unicode code points
const codePoints: string[] = [];
for (const char of glyph) {
const cp = char.codePointAt(0);
if (cp !== undefined) {
codePoints.push(`U+${cp.toString(16).toUpperCase().padStart(4, '0')}`);
}
}
// 2. Extract UTF-16 surrogate escape sequence
let utf16Surrogates = '';
for (let i = 0; i < glyph.length; i++) {
utf16Surrogates += `\\u${glyph.charCodeAt(i).toString(16).toUpperCase().padStart(4, '0')}`;
}
// 3. Extract UTF-8 binary bytes
const encoder = new TextEncoder();
const utf8Bytes = encoder.encode(glyph);
const utf8HexBytes = Array.from(utf8Bytes)
.map(b => '0x' + b.toString(16).toUpperCase().padStart(2, '0'))
.join(' ');
// 4. HTML Hex Entity
const htmlEntity = codePoints.map(cp => `&#x${cp.replace('U+', '')};`).join('');
// 5. Accurate Grapheme Count using Intl.Segmenter
let visualGraphemeCount = 0;
if (typeof Intl !== 'undefined' && 'Segmenter' in Intl) {
const segmenter = new Intl.Segmenter('en', { granularity: 'grapheme' });
visualGraphemeCount = Array.from(segmenter.segment(glyph)).length;
} else {
visualGraphemeCount = Array.from(glyph).length;
}
return {
glyph,
codePoints,
utf16Surrogates,
utf8HexBytes,
htmlEntity,
visualGraphemeCount
};
}
// Example Execution:
// Input: "π"
// codePoints: ["U+1F680"]
// utf16Surrogates: "\uD83D\uDE80"
// utf8HexBytes: "0xF0 0x9F 0x9A 0x80"
// visualGraphemeCount: 1
3. Algorithmic Principles & Unicode Specifications (UTS #51 & UAX #29)
Zero-Width Joiner (ZWJ) Sequences & Modifiers
Emojis can be combined sequentially using the invisible control character Zero-Width Joiner (U+200D):
[ Woman ] + [ ZWJ ] + [ Rocket ] = [ Woman Astronaut ]
(U+1F469) (U+200D) (U+1F680) (π©βπ)
Adding a Fitzpatrick skin-tone modifier (U+1F3FB through U+1F3FF) inserts additional code points directly following the base human emoji:
[ Woman ] + [ Medium-Dark Skin ] + [ ZWJ ] + [ Rocket ] = [ π©πΎβπ ]
(U+1F469) (U+1F3FE) (U+200D) (U+1F680)
In this compound sequence, what looks like 1 emoji on screen is physically made of 4 distinct Unicode code points, 7 JavaScript UTF-16 code units (length === 7), and 17 raw UTF-8 bytes!
The JavaScript String .length Trap & Grapheme Clusters
In JavaScript, the standard .length property returns the number of 16-bit code units, NOT the count of visual characters:
"A".length === 1"π".length === 2(High surrogate0xD83D+ Low surrogate0xDE80)"π¨βπ©βπ§βπ¦".length === 11(Family: Man + ZWJ + Woman + ZWJ + Girl + ZWJ + Boy)
// DANGEROUS: Slicing by string index corrupts surrogate pairs and ZWJs
const badSlice = "π Hello".slice(0, 1); // Returns an unprintable broken high surrogate "\uD83D"
// CORRECT: Using Intl.Segmenter to preserve grapheme cluster integrity
const segmenter = new Intl.Segmenter("en", { granularity: "grapheme" });
const segments = Array.from(segmenter.segment("π¨βπ©βπ§βπ¦ is a family"));
console.log(segments[0].segment); // Safely returns "π¨βπ©βπ§βπ¦"
MySQL utf8 vs utf8mb4 Encoding Trap
In MySQL and MariaDB, the historic character set labeled utf8 (or utf8mb3) only supports characters up to 3 bytes per character (up to U+FFFF). Standard 4-byte emojis (U+1F000 to U+1F9FF) require the utf8mb4 collation (utf8mb4_unicode_ci or utf8mb4_0900_ai_ci). Inserting an emoji into a legacy utf8 column triggers a fatal SQL error (Incorrect string value: '\xF0\x9F\x98\x80') or silently truncates the string.
4. Production Architecture & Software Engineering Integration
Use Case 1: Real-Time Chat & Social Feed Emoji Sanitization
In enterprise messaging backends (Slack, Discord, WhatsApp web clients), user inputs pass through a character segmentation pipeline before persistence:
[Client Chat Box: "Great job! ππ₯"]
|
v
[Input Length Limiter: Intl.Segmenter]
(Calculates 13 visual graphemes, not 16 surrogate units)
|
v
[Regex Emoji Normalization]
(Ensures skin-tone modifiers follow valid base glyphs)
|
v
[PostgreSQL / MySQL with utf8mb4]
(Persists full 4-byte UTF-8 sequences safely)
|
v
[Server-Sent Events (SSE) / WebSocket Broadcast]
(Dispatches normalized payload to connected clients)
Use Case 2: Cross-Platform Fallback Rendering
Different operating systems render identical Unicode emojis with wildly differing native font styles (Apple Color Emoji, Segoe UI Emoji on Windows, Noto Color Emoji on Android/Linux). Cross-platform web apps use libraries like Twemoji (Twitter) or JoyPixels to swap native system glyphs with consistent vector SVGs:
import twemoji from "twemoji";
export function renderUniversalEmoji(text: string): string {
return twemoji.parse(text, {
folder: "svg",
ext: ".svg",
base: "https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/"
});
}
5. Frequently Asked Questions (FAQs)
Why do some emojis show up as a blank box or question mark (tofu: ) on my computer?
When an emoji renders as a rectangular box (βtofuβ), it means the operating system or active browser font lacks a glyph for that specific Unicode code point. The Unicode Consortium releases new emoji versions annually (Emoji 14.0, 15.0, 16.0). Older operating systems (such as Windows 7 or older Android versions) that no longer receive system font updates cannot render newer emojis unless the web application bundles a custom web font or SVG replacement library.
What is the difference between UTF-8, UTF-16, and UTF-32 for emojis?
- UTF-8: Variable-width encoding using 1 to 4 bytes per character. Emojis occupy exactly 4 bytes each. UTF-8 is the standard encoding for the World Wide Web, JSON, and network protocols.
- UTF-16: Variable-width encoding using 2 or 4 bytes. Used internally by JavaScript, Java, and Windows APIs. Emojis above
U+FFFFare stored as two 16-bit surrogate pairs. - UTF-32: Fixed-width encoding using exactly 4 bytes (32 bits) for every code point. Computationally simple for indexing, but wastes significant memory for ASCII text.
How do Regional Indicator Symbols create country flag emojis?
Country flags do not have individual standalone emoji code points. Instead, Unicode defines 26 Regional Indicator Symbols corresponding to the Latin letters A through Z (U+1F1E6 π¦ through U+1F1FF πΏ). A national flag is created by pairing two consecutive indicator symbols matching the countryβs ISO 3166-1 alpha-2 code:
- United States (
US):U+1F1FA(Indicator U) +U+1F1F8(Indicator S) = πΊπΈ - United Kingdom (
GB):U+1F1EC(Indicator G) +U+1F1E7(Indicator B) = π¬π§
How can I reliably validate if a string contains only emojis in modern JavaScript?
Modern ECMAScript regex engines support Unicode Property Escapes (\p{...}):
// Matches strings composed solely of emojis and whitespace
const emojiOnlyRegex = /^(\p{Extended_Pictographic}|\p{Emoji_Presentation}|\s)+$/u;
console.log(emojiOnlyRegex.test("ππ")); // true
console.log(emojiOnlyRegex.test("π Hello")); // false
6. Client-Side Privacy & Security Guarantee
This Emoji Picker and Unicode Inspector tool is built on privacy-by-design principles:
- All search indexing, character frequency tracking, clipboard copying, and Unicode inspection occur 100% locally in your client browser.
- No typed search queries, copied glyphs, or message drafts are transmitted to any server or third-party marketing trackers.
- Works seamlessly in offline sandbox environments without an active internet connection.