blog

What is Unicode? Code points, planes, and why é is U+00E9

koboshi · Co-founder

Try it yourself

Everything in this article runs live in the converter. Paste your own text and watch every notation update at once.

Open the Unicode converter

Open the Unicode converter and type the single character é. The code point panel answers with U+00E9. That one line is the whole idea behind Unicode: every character in every writing system gets a permanent number, and this one happens to be E9 in hexadecimal, 233 in decimal.

Before Unicode, every vendor invented its own numbering. The byte 0xE9 meant é in Latin-1, something else entirely in a Russian code page, and nothing at all in ASCII, which stops at 0x7F. Moving a document between systems meant gambling on which table the receiving machine would use. Unicode ended that by defining one table for everybody, and it now covers more than 154,000 characters as of version 16.0, from Latin letters to CJK ideographs to Egyptian hieroglyphs.

A code point is a number, not a glyph

The number Unicode assigns is called a code point. By convention it is written U+ followed by at least four uppercase hex digits: U+0041 for A, U+4E2D for 中, U+1F600 for 😀. The notation only identifies the character. It says nothing about which bytes store it, which font draws it, or how wide it prints.

Each code point also carries a set of official properties. The letter é is formally named LATIN SMALL LETTER E WITH ACUTE, belongs to the Latin-1 Supplement block, and has general category Ll (lowercase letter). The converter's Inspect feature reports exactly these fields, looked up from the Unicode Character Database on your machine:

characters panel, Inspect output
é   U+00E9   LATIN SMALL LETTER E WITH ACUTE   Latin-1 Supplement   Ll   Latin

Planes: the map of the codespace

Code points run from U+0000 to U+10FFFF. That range is split into seventeen planes of 65,536 points each. Plane 0, the Basic Multilingual Plane, holds nearly every character in everyday use: Latin, Greek, Cyrillic, Arabic, Hebrew, CJK ideographs, Hangul and more. Plane 1 is the Supplementary Multilingual Plane, home to emoji, historic scripts and musical notation. The higher planes stay mostly empty, reserved for future growth.

One slice of the codespace is deliberately unusable. U+D800 through U+DFFF are surrogate code points, set aside so that UTF-16 can split large characters into two 16-bit halves. They do not represent characters and can never appear in well-formed text. A code point that does represent a character is called a Unicode scalar value, and that distinction matters the moment you start working with encodings.

One é, two ways to write it

Here is the part that surprises people. The é on your screen might be the single code point U+00E9, or it might be two code points: U+0065 LATIN SMALL LETTER E followed by U+0301 COMBINING ACUTE ACCENT. Both render identically. Both are valid. They compare as different strings in most programming languages.

javascript
"\u00E9" === "\u0065\u0301"   // false, even though both look like é
"\u00E9".length                 // 1
"\u0065\u0301".length          // 2

Unicode calls the first form precomposed and the second decomposed, and its normalization rules (NFC and NFD) convert between them. What you perceive as one character is a grapheme cluster, which can be built from several code points. Emoji push this further: the family emoji is four code points glued together with zero width joiners.

Unicode assigns the numbers. Fonts draw the shapes. Encodings like UTF-8 and UTF-16 decide the bytes. Keeping those three jobs separate is the key to reading any Unicode document without confusion.

Blocks, scripts and names

The standard organizes code points into named blocks, contiguous ranges like Basic Latin (U+0000..U+007F) or CJK Unified Ideographs (U+4E00..U+9FFF). Blocks are a storage detail, a way to slice the codespace. Scripts are a linguistic property: the script of 中 is Han, and Han characters also appear in blocks outside the main CJK range. Character names are fixed forever once published, which is why a few famous typos from the 1990s are still official names today.

Putting it to work

When a bug report says "the text is broken," the first question is always which numbers are actually in the file. Paste the text into the converter and the answer is immediate:

  • The U+ and 0x panels show the code points, one per character.
  • Inspect on the Characters panel gives each character its name, block, category and script.
  • Invisible characters, like zero width spaces or bidi controls, finally show up as numbers instead of nothing.

The next piece of the puzzle is how those numbers become bytes. That is UTF-8 and UTF-16, and they are encodings, not the character set itself. The difference trips up even experienced developers, so it gets its own article.

Try it yourself

Everything in this article runs live in the converter. Paste your own text and watch every notation update at once.

Open the Unicode converter