Find Unicode characters by name or code point, preview symbols, and copy the exact character you need in your browser.
U+2764 or 0x2764, or search by name fragment ("heart", "regional indicator s"). The lookup accepts BMP codepoints (U+0000βU+FFFF) and supplementary codepoints (U+10000βU+10FFFF) up to the Unicode maximum of U+10FFFF.U+2764), official Unicode name (HEAVY BLACK HEART), General Category (So β Symbol, Other), and Block (Dingbats). The encoding panel lists UTF-8 bytes (hex), UTF-16 code units (with surrogate pair if astral), UTF-32, HTML numeric entity (❤ / ❤), JavaScript escape (β€ for BMP or \u{1F600} for ES6 astrals), Python escape (β€ or \U0001F600), and URL percent-encoding.Latin Extended-A, CJK Unified Ideographs, Emoticons, Miscellaneous Symbols and Pictographs, or Supplemental Symbols and Pictographs. Useful when you remember a script but not the codepoint.Unicode assigns a unique number β a code point β to every character used in human writing systems, plus emoji, symbols, control codes, and private-use areas. The standard reserves the range U+0000 through U+10FFFF (about 1.1 million slots, of which roughly 155,000 are assigned as of Unicode 16.0). Knowing the exact codepoint and encoding of a character is essential when you're debugging mojibake, building a regex, sanitizing user input, or working with internationalization. Typical scenarios:
Γ© shows up as ΓΒ© it's usually UTF-8 bytes (0xC3 0xA9) being decoded as Latin-1. Looking up the codepoint and its byte pattern confirms what encoding the source actually used."πΊπΈ".length returns 4 because the flag is two astral characters, each a UTF-16 surrogate pair. Looking up the components clarifies why naive .length and [i] indexing break on emoji.Γ© (NFC, U+00E9) and e + combining acute (NFD, U+0065 U+0301) look identical but compare unequal. Codepoint inspection reveals which normalization form your data uses..notdef box means the rendering font lacks that codepoint; the lookup tells you the block so you can pick a font that covers it (e.g., Noto Sans CJK for U+4E00βU+9FFF).Related encoding tools: ASCII Table for the 7-bit ASCII subset, Base64 Encoder for binary-safe transport, Hex Dump Viewer to see raw UTF-8 bytes of a file, and Number Base Converter for codepoint hex/decimal/binary.
Unicode's 21-bit code space is divided into 17 planes of 65,536 codepoints each. Most everyday text lives in Plane 0; emoji, historic scripts, and CJK extensions live above.
| Plane | Range | Name | Contents |
|---|---|---|---|
| 0 | U+0000βU+FFFF | BMP (Basic Multilingual Plane) | Latin, Greek, Cyrillic, Arabic, Hebrew, Devanagari, Hangul, common CJK, currency, math, arrows |
| 1 | U+10000βU+1FFFF | SMP (Supplementary Multilingual) | Linear B, cuneiform, Egyptian hieroglyphs, musical notation, emoji (U+1F300+), playing cards |
| 2 | U+20000βU+2FFFF | SIP (Supplementary Ideographic) | CJK Unified Ideographs Extension BβF (rare/historic Chinese characters) |
| 3 | U+30000βU+3FFFF | TIP (Tertiary Ideographic) | CJK Extension GβH, Small Seal Script (since Unicode 13.0) |
| 4β13 | U+40000βU+DFFFF | Unassigned | Reserved for future allocation |
| 14 | U+E0000βU+EFFFF | SSP (Supplementary Special-purpose) | Language tags (U+E0000+), variation selectors VS17βVS256 (U+E0100+) |
| 15 | U+F0000βU+FFFFF | SPUA-A (Supplementary Private Use A) | Vendor/app-specific glyphs (Apple, ConScript Unicode Registry) |
| 16 | U+100000βU+10FFFF | SPUA-B (Supplementary Private Use B) | Additional private use |
Codepoints in Plane 0 are called "BMP" characters and fit in a single UTF-16 code unit. Codepoints in Planes 1β16 are called supplementary or astral characters and require a UTF-16 surrogate pair (two 16-bit code units) β this is what trips up String.length in JavaScript, Java, and C#.
UTF-8 is variable-width (1β4 bytes), UTF-16 is also variable-width (2 or 4 bytes), and UTF-32 is always 4 bytes. Pick UTF-8 for storage and the web; pick UTF-16 in-memory for Java/JavaScript/.NET interop; UTF-32 is rare outside academic and Python-3 internal string code.
| Codepoint | Example | UTF-8 bytes | UTF-16 code units | UTF-32 |
|---|---|---|---|---|
U+0041 (A, ASCII) |
A | 1 byte (0x41) |
1 (0x0041) |
4 (0x00000041) |
U+00E9 (Γ©, Latin-1) |
Γ© | 2 bytes (0xC3 0xA9) |
1 (0x00E9) |
4 |
U+20AC (β¬, Euro sign) |
β¬ | 3 bytes (0xE2 0x82 0xAC) |
1 (0x20AC) |
4 |
| U+4E2D (CJK ideograph) | δΈ | 3 bytes (0xE4 0xB8 0xAD) |
1 (0x4E2D) |
4 |
U+1F600 (π, grinning face) |
π | 4 bytes (0xF0 0x9F 0x98 0x80) |
2 β surrogate pair (0xD83D 0xDE00) |
4 |
| U+1F1FA U+1F1F8 (flag) | πΊπΈ | 8 bytes (2Γ 4) | 4 code units / 8 bytes (2 surrogate pairs) | 8 |
π¨βπ©βπ¦ (family ZWJ seq) |
π¨βπ©βπ¦ | 18 bytes (4+3+4+3+4) | 16 bytes (3 surrogate pairs + 2 BMP units) | 20 |
The family emoji is MAN (U+1F468) + ZWJ (U+200D) + WOMAN (U+1F469) + ZWJ + BOY (U+1F466) β five separate codepoints rendered as one glyph by the font.
A code point is the abstract number Unicode assigns to a character β for example, U+1F600 for the grinning face. A code unit is the storage unit of a specific encoding: 8 bits for UTF-8, 16 bits for UTF-16, 32 bits for UTF-32. The grinning face is a single code point but takes 4 UTF-8 code units, 2 UTF-16 code units (a surrogate pair), or 1 UTF-32 code unit. JavaScript's str.length and str[i] count UTF-16 code units, which is why "π".length === 2. Use [...str].length or Intl.Segmenter for grapheme counts.
UTF-8 uses variable-width encoding. Codepoints in U+0000βU+007F (ASCII) take 1 byte; U+0080βU+07FF take 2 bytes; U+0800βU+FFFF take 3 bytes (this includes most CJK in the BMP); U+10000βU+10FFFF take 4 bytes (most emoji, ancient scripts, CJK Extension B+). A "simple" emoji like π (U+1F600) is in Plane 1 so it's 4 UTF-8 bytes, while the heart β€ (U+2764) is in the BMP Dingbats block and only takes 3 bytes.
Country flags don't have their own codepoints. Each flag is a sequence of two regional indicator symbols in the range U+1F1E6βU+1F1FF (which correspond to the letters AβZ). πΊπΈ is U+1F1FA (regional indicator U) + U+1F1F8 (regional indicator S). The font sees the pair and renders the US flag; if the font doesn't have flag support, you see two letter boxes. Of the 676 possible AAβZZ pairs, only the ~270 matching ISO 3166-1 alpha-2 country codes render as flags. In UTF-8 each flag takes 8 bytes (two 4-byte astrals); in UTF-16 it's 8 bytes (two surrogate pairs).
ZWJ is U+200D (Zero-Width Joiner), an invisible glue character. Placed between emoji codepoints, it tells the renderer to fuse them into a single composite glyph if the font supports it. Examples: π¨βπ©βπ¦ is MAN + ZWJ + WOMAN + ZWJ + BOY; π³οΈβπ is WHITE FLAG + VS16 + ZWJ + RAINBOW; π©βπ¬ is WOMAN + ZWJ + MICROSCOPE. If the font lacks the composite glyph (older Android, plain-text terminals), each component renders separately with the ZWJ as nothing. Splitting an emoji string by codepoint will break ZWJ sequences β always segment by grapheme cluster.
Variation selectors are invisible codepoints that follow a base character to pick a visual variant. The two common ones are U+FE0E (VS15, text style) and U+FE0F (VS16, emoji style). Many characters defined before emoji existed (β, β€, β, β ) have both text and emoji presentations; appending VS16 forces colorful emoji rendering, while VS15 forces monochrome text style. There are also 240 additional variation selectors in Plane 14 (U+E0100βU+E01EF) used for Ideographic Variation Sequences in CJK. Selectors are zero-width β they don't display on their own but change the previous character's appearance.
Combining characters modify the base character that precedes them β primarily accents and diacritics. The combining range U+0300βU+036F includes U+0301 combining acute (Μ), U+0308 combining diaeresis (Μ), U+0303 combining tilde, and others. So Γ© can be stored as a single precomposed codepoint U+00E9 (NFC form) or as e + U+0301 (NFD form) β both display identically but compare unequal in byte-wise string comparison. Use Unicode normalization (String.prototype.normalize('NFC') in JS, unicodedata.normalize in Python) before comparing or storing user input. "Zalgo" text is just dozens of combining marks stacked on each base character.
[a-z] not match Γ© or ζ₯?Plain character classes like [a-z] match only the ASCII range U+0061βU+007A. To match Unicode letters across all scripts, use the u flag and Unicode property escapes: /\p{Letter}/u (or \p{L}) matches any letter codepoint, \p{Lu} matches uppercase letters, \p{Script=Han} matches CJK ideographs, and \p{Emoji} matches emoji codepoints. This works in JavaScript (since ES2018), Python's regex package (not the stdlib re), Java (via \p{IsAlphabetic}), and PCRE. Without the u flag, regex engines treat astral codepoints as two separate surrogate code units, breaking matches mid-character.
The Byte Order Mark is U+FEFF placed at the start of a stream. In UTF-16/UTF-32 it signals endianness (BE vs LE). In UTF-8 it's just an encoding signature (0xEF 0xBB 0xBF) β the bytes have no byte-order ambiguity. A UTF-8 BOM helps Windows tools auto-detect encoding but breaks Unix shebangs, JSON parsers, and some web servers. Recommendation: never write a BOM in UTF-8 unless a Windows-specific consumer demands it; always strip it on read. For UTF-16/UTF-32, the BOM is essentially mandatory unless the byte order is fixed by protocol (e.g., UTF-16BE in text/plain; charset=UTF-16BE).
Three layers disagree: bytes, code units, and grapheme clusters. "π¨βπ©βπ¦" is 1 grapheme but 5 codepoints, 11 UTF-16 code units, and 18 UTF-8 bytes. Languages vary: Python 3 len(s) returns codepoint count; JavaScript/Java/C# .length returns UTF-16 code units; Go len(s) returns bytes (and utf8.RuneCountInString returns codepoints); Rust .len() is bytes and .chars().count() is codepoints. For user-visible character count (graphemes), use Intl.Segmenter in JavaScript, \X in PCRE2/Perl, or the unicode-segmentation crate in Rust. None of the built-in .length methods give you what a user would call "one character" for emoji or Indic scripts.