UTF-8 vs UTF-16 vs UTF-32
Unicode assigns numbers to characters; UTF-8, UTF-16 and UTF-32 are three ways to turn those numbers into bytes. They differ in size, complexity and where they're used.
The three encodings
| Encoding | Bytes per character | Notes |
|---|---|---|
| UTF-8 | 1–4 (variable) | ASCII-compatible; dominates the web and files |
| UTF-16 | 2 or 4 (surrogate pairs) | Used internally by JavaScript, Java, Windows |
| UTF-32 | 4 (fixed) | Simple indexing, but wasteful; rarely stored |
Why UTF-8 won the web
UTF-8 is backward-compatible with ASCII (English text is unchanged and 1 byte per character), compact for most content, and has no byte-order issues. It's the default for HTML, JSON, and most modern systems.
Where UTF-16 shows up
JavaScript strings are UTF-16 internally, which is why '😀'.length is 2 — the emoji is stored as a “surrogate pair” of two 16-bit units. This trips up a lot of string-length logic.
.length.Frequently asked questions
Which Unicode encoding should I use?
UTF-8 for files, web pages and APIs. It's compact, ASCII-compatible and the web standard.
Why is emoji length 2 in JavaScript?
JS strings are UTF-16; emoji beyond the basic range take two 16-bit units (a surrogate pair), so .length counts 2.