A code point is the number Unicode gives to each character
Unicode is a table that gives every character a number, and that number is called a code point. The letter é is U+00E9 (decimal 233), A is U+0041 (65) and 😀 is U+1F600 (128512). The value after U+ is hexadecimal, padded with zeros to at least four digits. Numbers run from U+0000 to U+10FFFF, 1,114,112 in all, and Unicode 18.0, released in 2026, assigns 172,808 characters among them.
This tool puts a text box and a code box side by side and rewrites the other one whenever you edit either. Code can be written as U+ notation, as \u00E9 for JavaScript and JSON, \u{E9} for ES2015, \U0001F600 for Python, é and é for HTML, \E9 for CSS, or as a decimal or 0x number: nine notations, and a pasted value in any of them is recognized and decoded. The card below shows the official name, block, general category and version of the selected character, and the code space map shows where it sits among the 1,114,112 code points.
When you need to look at code points
Most of the time you never need a character's number. You need it when text looks broken, when you cannot type a character into code, or when what you see differs from what is stored.
- Reading logs and API responses: text such as
Caf\u00E9in a server log or JSON response is not readable at a glance. Paste it into the code box and it turns into Café. - Putting symbols in web pages: a symbol that is hard to type goes into HTML as
→(→) or into a CSS content value as"\2192". Every place has its own syntax, so you often have to rewrite one character in several notations. - Length limits and storage size: 👩💻 is one visible character, but it is 3 code points, a JavaScript length of 5 and 11 bytes in UTF-8. Depending on which unit a form limit or a database column counts, the same text can pass or get cut off.
- Decomposed accents: file names on a macOS HFS Plus volume are stored fully decomposed, so a name like résumé.pdf can be made of e plus U+0301 instead of é (U+00E9). Copied elsewhere, such a name may look identical yet fail an exact comparison or a search.
- Finding invisible characters: a zero-width space (U+200B) hiding in a copied order number or address makes comparison and search fail even though both look the same. A BOM (U+FEFF) at the start of a file can also end up glued to the first CSV header and change its name.
- Boxes instead of characters: when a character shows as a box (□) or a question mark, you need to tell an unassigned number from a character added in a recent version that your device font does not have yet. The name and the Added in line on the card help with that.
- Escapes in code: JSON, JavaScript and HTML each want a different escape for the same character, and a string with emoji needs surrogate pairs in some of them. Check them here before pasting them into source.
How to use it
- Type or paste characters into the text box and the code box shows their code points. Going the other way, enter
U+00E9,\u00E9oréinto the code box and the characters appear in the text box. Separate several values with spaces or commas. - Pick one of the notation buttons: U+, decimal, 0x, \u, \u{…}, Python, HTML hex, HTML decimal or CSS. If the code box holds another notation, the button rewrites it in the one you chose, so it also works as a notation-to-notation converter.
- With Keep ASCII as is on, escape notations leave letters, digits and symbols alone and only convert the rest. Turn it off to write every character as a number. The AB and ab buttons set the case of the hex digits.
- Select a cell in the code point strip to see its name, block, category, version and ten values on the card. The copy button at the end of a line copies only that one notation.
- Select a plane or a cell on the code space map, or use the ‹ › buttons on the card, to browse the neighbors. Add a character you want to the text box with Add to text box.
Nine ways to write the same character
A code point is one number, but each place you use it has its own syntax. The table shows é (U+00E9) and 😀 (U+1F600) in each notation. Because 😀 is above U+FFFF, some notations write it as one piece and others split it in two.
| Notation | é | 😀 | Where it is used |
|---|---|---|---|
| U+ notation | U+00E9 | U+1F600 | Unicode documents, character charts and prose |
| Decimal | 233 | 128512 | Numeric values in programs (JavaScript codePointAt, Python ord) |
| 0x hexadecimal | 0x00E9 | 0x1F600 | Numeric constants and arrays in C, Java and similar languages |
| \u escape | \u00E9 | \uD83D\uDE00 | JavaScript, JSON and Java strings (UTF-16 units) |
| \u{…} escape | \u{E9} | \u{1F600} | JavaScript since ES2015, Rust and Swift strings |
| Python | \u00E9 | \U0001F600 | Python strings (\U takes eight digits) |
| HTML hex | é | 😀 | HTML and XML documents |
| HTML decimal | é | 😀 | HTML and XML documents |
| CSS | \E9 | \1F600 | CSS content values and selectors |
| UTF-8 bytes | C3 A9 | F0 9F 98 80 | The actual bytes in files and on the network |
| UTF-16 units | 00E9 | D83D DE00 | The unit JavaScript, Java and Windows use to hold text |
JSON and Java take exactly four digits after \u, so a character above U+FFFF is written as the surrogate pair described in the next section. Python separates the four-digit \u from the eight-digit \U. CSS takes one to six hex digits after the backslash and ends the escape with a single space if a hex digit or a space follows. An HTML character reference is closed with a semicolon. The tool understands all of these rules when it reads pasted text, so escapes and character references can be mixed in one piece of text. U+ and 0x values are read only as a list separated by spaces or commas; mixed in with escapes they stay as plain text, and the tool says so. HTML numeric references € to Ÿ follow the HTML Standard and map through the Windows-1252 table (– becomes –).
Why 😀 is written as two escapes, \uD83D\uDE00
UTF-16 stores text in 16-bit units. Sixteen bits reach only U+FFFF, so a larger code point is written as two values from a reserved range (U+D800 to U+DFFF) called surrogates. For 😀 (U+1F600) the calculation goes like this.
- Subtract 0x10000 from the code point: 0x1F600 − 0x10000 = 0xF600.
- Split the remaining 20 bits into the top 10 and the bottom 10. For 0xF600 the top 10 bits are 0x3D and the bottom 10 are 0x200.
- Add 0xD800 to the top value and 0xDC00 to the bottom one: 0xD800 + 0x3D = 0xD83D and 0xDC00 + 0x200 = 0xDE00.
| Character | Code point | UTF-16 (surrogate pair) | UTF-8 bytes |
|---|---|---|---|
| 😀 | U+1F600 | D83D DE00 | F0 9F 98 80 |
| 👍 | U+1F44D | D83D DC4D | F0 9F 91 8D |
| 𝄞 | U+1D11E | D834 DD1E | F0 9D 84 9E |
| 𠀀 | U+20000 | D840 DC00 | F0 A0 80 80 |
That is why '😀'.length is 2 in JavaScript and why JSON writes \uD83D\uDE00. A high surrogate (D800 to DBFF) must be followed by a low surrogate (DC00 to DFFF); one on its own is not a character. The tool reports a surrogate value such as U+D800, or an unpaired \uD83D, as an error.
Four ways to count characters
The number of characters depends on what you count. What looks like one character on screen is a grapheme cluster as defined by UAX #29. The code point count is the number of Unicode numbers, the UTF-16 length is the value JavaScript returns for length, and UTF-8 bytes are the size once the text is saved to a file. The four boxes above the text box show these values.
| Text | Visible characters | Code points | UTF-16 | UTF-8 bytes | What differs |
|---|---|---|---|---|---|
| A | 1 | 1 | 1 | 1 | With ASCII all four values are equal |
| é | 1 | 1 | 1 | 2 | An accented Latin letter takes 2 bytes in UTF-8 |
| € | 1 | 1 | 1 | 3 | The euro sign takes 3 bytes but a single UTF-16 unit |
| é (e + U+0301) | 1 | 2 | 2 | 3 | A combining accent attaches to the letter before it |
| 😀 | 1 | 1 | 2 | 4 | Above U+FFFF, so two UTF-16 units |
| 👍🏽 | 1 | 2 | 4 | 8 | A skin tone modifier (U+1F3FD) is attached |
| 🇺🇸 | 1 | 2 | 4 | 8 | A flag is two regional indicator letters, U and S |
| 👩💻 | 1 | 3 | 5 | 11 | A ZWJ (U+200D) joins two emoji |
So before you set a limit such as "at most 20 characters", decide what is being counted. People feel visible characters, storage cares about UTF-8 bytes, and the positions used by slice and substring in JavaScript are UTF-16 units. Cutting an emoji in the middle at a UTF-16 boundary leaves an unpaired surrogate, which shows up as a broken character (�).
Hangul syllables: a formula for the code point
The 11,172 precomposed Hangul syllables (U+AC00 to U+D7A3) are laid out as 19 initials × 21 vowels × 28 finals (including no final), so their numbers can be calculated. Section 3.12 of the Unicode standard gives the formula below, with every index counted from 0.
code point = 0xAC00 + (initial × 21 + vowel) × 28 + final
| Syllable | Initial | Vowel | Final | Calculation | Code point |
|---|---|---|---|---|---|
| 가 | ㄱ 0 | ㅏ 0 | none 0 | AC00 + (0 × 21 + 0) × 28 + 0 | U+AC00 |
| 한 | ㅎ 18 | ㅏ 0 | ㄴ 4 | AC00 + (18 × 21 + 0) × 28 + 4 = AC00 + 10,588 | U+D55C |
| 힣 | ㅎ 18 | ㅣ 20 | ㅎ 27 | AC00 + (18 × 21 + 20) × 28 + 27 = AC00 + 11,171 | U+D7A3 |
In the other direction, subtract 0xAC00 and divide by 588 (21 × 28): the quotient is the initial, the remainder divided by 28 gives the vowel, and what is left is the final. The card's As jamo line shows the same syllable split into the Hangul Jamo block, and the official name of a syllable comes from the same rule, so 한 is HANGUL SYLLABLE HAN.
The code space map: 17 planes
The 1,114,112 code points are divided into 17 planes of 65,536 (0x10000). Whatever precedes the last four digits is the plane number: the 1 in U+1F600. On the tool's map a large board is one plane split into 256 cells of 256 code points each, and a cell is colored by the group of block that fills most of it.
| Plane | Range | Name | What it holds |
|---|---|---|---|
| 0 | U+0000 to U+FFFF | Basic Multilingual Plane (BMP) | Latin, Greek, Cyrillic, Hangul, common Han, kana and most scripts in use today, the surrogates (D800 to DFFF) and the private use area (E000 to F8FF) |
| 1 | U+10000 to U+1FFFF | Supplementary Multilingual Plane (SMP) | Most emoji, historic scripts, math letters, musical symbols |
| 2 | U+20000 to U+2FFFF | Supplementary Ideographic Plane (SIP) | CJK Unified Ideographs Extensions B to F and I, CJK Compatibility Ideographs Supplement |
| 3 | U+30000 to U+3FFFF | Tertiary Ideographic Plane (TIP) | CJK Unified Ideographs Extensions G, H and J, Seal (Unicode 18.0) |
| 4 to 13 | U+40000 to U+DFFFF | Unassigned | No characters assigned yet |
| 14 | U+E0000 to U+EFFFF | Supplementary Special-purpose Plane (SSP) | Tag characters, variation selectors supplement |
| 15 and 16 | U+F0000 to U+10FFFF | Supplementary Private Use Area-A and B | Areas that organizations or fonts define for themselves |
The two widest stretches in plane 0 are the CJK Unified Ideographs (U+4E00 to U+9FFF, 20,992 code points) and the Hangul syllables (U+AC00 to U+D7A3, 11,172 characters). Just after them, U+D800 to U+DFFF is reserved for surrogates and holds no characters, and U+E000 to U+F8FF is a private use area left nameless. Planes 1 to 16 are all written as surrogate pairs in UTF-16.
Characters you cannot see
Characters that look like spaces, or do not show at all, still have code points. The code point strip and the card show them as labels in dashed boxes, so you can tell at once what is hiding in pasted text.
| Label | Code point | Official name | Where it turns up |
|---|---|---|---|
| NBSP | U+00A0 | NO-BREAK SPACE | in web pages, glued spaces in word processors |
| ZWSP | U+200B | ZERO WIDTH SPACE | Text copied from the web, places that mark where a line may break |
| ZWJ | U+200D | ZERO WIDTH JOINER | The joint that makes two emoji one, as in 👩💻 |
| VS16 | U+FE0F | VARIATION SELECTOR-16 | Asks for the color emoji look, as in ❤️ |
| BOM | U+FEFF | ZERO WIDTH NO-BREAK SPACE (byte order mark) | The very start of files saved by some editors |
| IDSP | U+3000 | IDEOGRAPHIC SPACE | Japanese and Chinese text, spaces typed in full-width mode |
| HF | U+3164 | HANGUL FILLER | Looks blank, so it is sometimes used in nicknames |
| SHY | U+00AD | SOFT HYPHEN | A hyphen that shows only where a word is split at the end of a line |
A line break is a character too. Windows Notepad ends a line with two characters, CR (U+000D) and LF (U+000A), while macOS and Linux often use LF alone. A browser text box, however, turns a pasted CR LF into a single LF, so to see the line endings of a file as they are you need a tool that shows bytes, such as a UTF-8 hex converter.
Normalization: NFC and NFD
Unicode sometimes allows the same text to be written in two ways. The single é (U+00E9) and the pair e plus a combining acute accent (U+0065 U+0301) look identical, and Unicode treats them as the same text (canonical equivalence). Forcing the combined form is called NFC and forcing the split form NFD (UAX #15). Hangul works the same way: 한 is U+D55C in NFC and three jamo, U+1112 U+1161 U+11AB, in NFD.
| Character | NFC (combined) | NFD (split) |
|---|---|---|
| é | U+00E9 | U+0065 U+0301 |
| Å | U+00C5 | U+0041 U+030A |
| ñ | U+00F1 | U+006E U+0303 |
| ö | U+00F6 | U+006F U+0308 |
Comparison, search and file names often treat different normalization forms as different values. If the text box contains decomposed characters, the tool tells you, and the Combine to NFC and Split to NFD buttons convert everything at once. Compatibility normalization (NFKC and NFKD), which folds shapes such as half-width and full-width forms or ① and 1 together, is not done here.
Common mistakes
- Writing the value after U+ in decimal: the E9 in U+00E9 is hexadecimal. Writing the decimal 233 as U+233 gives a different character altogether. The tool reads a bare number as hexadecimal and, if it consists only of digits, offers a button to read it as decimal.
- Copying surrogate values as code points: turning
\uD83D\uDE00into U+D83D U+DE00 does not give a character. The code point is the single U+1F600. - Digits after
\u:\uin JavaScript and JSON takes exactly four digits, and\Uin Python exactly eight.\u1F600is read as U+1F60 (ὠ) followed by the digit 0. - Digits after a CSS escape: in CSS,
"\00E91"is read as U+00E91. To write a 1 after é, end the escape with a single space:"\00E9 1". - Dropping the semicolon in an HTML reference:
éwithout the semicolon is read differently depending on what follows it, or treated as an error. Close it asé. - Judging by shape: Latin A (U+0041), Greek Α (U+0391) and Cyrillic А (U+0410) look the same but are different characters. Mixed into an address or an ID, they break search and login, so check with the code points.
Limits
- Names, blocks, general categories and versions come from Unicode 18.0 data. Shapes are drawn by your device's fonts, so a character that is in the data can still show as a box.
- Visible characters are counted with the browser's grapheme rules (Intl.Segmenter). Depending on the Unicode version your browser knows, recent emoji sequences may be counted differently.
- Python's
\N{name}notation and octal escapes are not read.\xis read as a code point (U+0000 to U+00FF), not as a byte, so use a UTF-8 hex converter to decode UTF-8 bytes into text. - CSS reads
\0, surrogates and values above U+10FFFF as U+FFFD, but this tool reports surrogates and out-of-range values as errors. - Compatibility normalization (NFKC and NFKD), changing case and searching by character name are not included.
- The text box converts up to 200,000 characters, and the code point strip draws the first 400.
- Conversion happens only in your browser. The tool downloads the character name data file once, and the characters or codes you enter are never sent to a server.
Basis: U+ notation, planes, surrogates and the Hangul syllable rule follow the Unicode 18.0 core specification; names, blocks and versions follow the Unicode 18.0 Character Database (UCD); escape syntax follows the ECMAScript, Python, HTML and CSS specifications and RFC 8259, all checked on October 22, 2026. The values in the tables were recomputed with this tool's conversion core and compared.
Sources
- 01Unicode 18.0 Appendix A: Notational ConventionsA code point is U+ followed by four to six hex digits, padded with zeros when shorter
- 02Unicode 18.0 2.8.1: PlanesCode space 0 to 10FFFF (1,114,112), BMP, SMP, SIP, TIP, SSP and private use planes
- 03Unicode 18.0 3.9.2: UTF-16Characters above U+FFFF are two units, a surrogate pair
- 04Unicode 18.0 3.12: Hangul Syllable DecompositionSBase AC00, 19 initials, 21 vowels, 28 finals, 11,172 syllables
- 05Unicode 18.0 4.8.1: Unicode Name PropertyThe rules that build Hangul syllable and CJK ideograph names (Table 4-8)
- 06Unicode 18.0.013,007 characters added, 172,808 in all
- 07Unicode Character Database 18.0Names (UnicodeData), blocks (Blocks), version added (DerivedAge)
- 08UAX #29: Unicode Text SegmentationThe grapheme cluster, what looks like one character on screen
- 09UAX #15: Unicode Normalization FormsNFC, NFD and canonical equivalence
- 10ECMA-262: String LiteralsJavaScript's \uXXXX and \u{…} escapes
- 11Python Language Reference: Escape sequences\uxxxx (four digits), \Uxxxxxxxx (eight digits), \N{name}
- 12HTML Standard: Character referencesDecimal and hexadecimal numeric references, and named references
- 13CSS Syntax Level 3: Consume an escaped code pointA backslash and one to six hex digits; one trailing space ends the escape
- 14RFC 8259 section 7: StringsJSON writes characters above U+FFFF as a pair, like \uD834\uDD1E
- 15MDN: String lengthThe length of a JavaScript string is its number of UTF-16 code units
- 16Apple TN1150: HFS Plus Volume FormatHFS Plus stores file names in fully decomposed form
Frequently asked questions
What is the Unicode code point of é?
The precomposed é is U+00E9, decimal 233. In JavaScript and JSON you write it as \u00E9, in HTML as é or é, and in UTF-8 it takes two bytes, C3 A9. A decomposed é is a different sequence: e (U+0065) plus a combining acute accent (U+0301).
How do I turn a code like U+00E9 back into a character?
Enter U+00E9 in the code box and the text box shows é. Values written in other notations, such as \u00E9, é, é or 0xE9, can be pasted as they are and the tool recognizes the notation. Separate several values with spaces or commas.
Why does 😀 show up as two escapes like \uD83D\uDE00?
😀 is a single code point, U+1F600. The \u escape in JavaScript, JSON and Java takes exactly four hex digits (one UTF-16 unit), so anything above U+FFFF is written as a surrogate pair, \uD83D\uDE00. \u{1F600} and Python's \U0001F600 write it as one.
Why is the length of one emoji 2 or 5?
JavaScript's length counts UTF-16 units. 😀 is one code point but two UTF-16 units, and 👩💻 is three code points (U+1F469, U+200D, U+1F4BB), which makes five units. This tool shows visible characters, code points, UTF-16 length and UTF-8 bytes side by side.
Why do two identical-looking é have different code points?
A precomposed é is one code point, U+00E9, while a decomposed é is two, e (U+0065) and a combining accent (U+0301). They look the same and Unicode treats them as equivalent, but exact string comparison can tell them apart. The Combine to NFC button makes them match.
How do I find characters I cannot see?
Paste the text into the text box. The code point strip labels zero-width spaces (ZWSP, U+200B), the byte order mark (BOM, U+FEFF) and no-break spaces (NBSP, U+00A0) in dashed boxes. That helps when a copied order number or address behaves strangely.
How many code points does Unicode have?
U+0000 to U+10FFFF is 1,114,112 code points, split into 17 planes of 65,536. Unicode 18.0 assigns 172,808 characters. The surrogate range U+D800 to U+DFFF is never used for characters.
Is the text I enter sent to a server?
No. Conversion happens only in your browser. The tool downloads the Unicode 18.0 data file once to show character names, but the characters or codes you enter are never sent or stored.