CJK in Unicode: Han unification, blocks, and gotchas
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 converterType the single character 中 into the Unicode converter. The U+ panel answers U+4E2D, and Inspect names it CJK UNIFIED IDEOGRAPH-4E2D, block CJK Unified Ideographs, script Han. The encoding panels show what that code point becomes on the wire:
Unicode U+ notation: U+4E2D
UTF-8 code units: E4 B8 AD
UTF-16 code units: 4E2D
Hex NCRs: 中UTF-8 spends three bytes here because U+4E2D sits in the U+0800..U+FFFF bracket where RFC 3629 uses the three-byte form. UTF-16 gets the same character into one 16-bit code unit because it lives in the Basic Multilingual Plane. Both encode the same code point; only the byte layout differs, as covered in Unicode vs UTF-8.
One code point, three writing traditions
Chinese, Japanese, Korean and historical Vietnamese all write with Han ideographs, and Unicode encodes each ideograph exactly once. This decision, called Han unification, is the most debated part of the standard, so it helps to know the actual rule. Chapter 18 of The Unicode Standard models every ideograph with three attributes: a semantic value (what it means), an abstract shape (its structural form), and an actual shape (what a specific typeface draws). Unicode encodes the abstract shape. Differences on the typeface axis, the small regional variations in how a stroke bends or terminates, are deliberately not encoded.
The consequence is visible every day: the same code point renders with slightly different glyphs in a Chinese font and a Japanese font, while the bytes underneath are identical. Which regional form a reader sees is chosen by the font, typically picked from the document's language tagging, for example lang="zh-CN" versus lang="ja" in HTML. When a specific regional form must survive in plain text, the standard provides standardized ideographic variation sequences for exactly that job.
Unification has hard limits. The Source Separation Rule says that ideographs encoded separately in any source standard must stay separate in Unicode, so that legacy CJK encodings round-trip without loss. The Noncognate Rule says historically unrelated ideographs are never unified, even when they look alike. Together these rules explain why the code charts contain pairs that look identical to an untrained eye yet occupy different code points.
Unicode encodes the abstract shape of an ideograph. The font, guided by the document's language, decides what that shape looks like on screen.
The main block and the extensions
The original block, CJK Unified Ideographs, runs from U+4E00 to U+9FFF and holds 20,992 ideographs. That is the everyday repertoire, but it filled up long ago. Growth spilled into nine extension blocks: Extension A sits in the BMP right below the main block, Extensions B through I live on the higher planes. The ranges and counts below come from the Unicode Character Database, version 16.0:
Block Range Chars
CJK Unified Ideographs U+4E00..U+9FFF 20,992
Extension A U+3400..U+4DBF 6,592
Extension B U+20000..U+2A6DF 42,720
Extension C U+2A700..U+2B739 4,154
Extension D U+2B740..U+2B81D 222
Extension E U+2B820..U+2CEA1 5,762
Extension F U+2CEB0..U+2EBE0 7,473
Extension G U+30000..U+3134A 4,939
Extension H U+31350..U+323AF 4,192
Extension I U+2EBF0..U+2EE5D 622Everything from Extension B upward sits above U+FFFF, so each of those ideographs is a surrogate pair in UTF-16. 𠀀, the first character of Extension B, is U+20000, encodes as the code units D840 DC00, and reports "𠀀".length === 2 in JavaScript. Extension I is the newest resident of this list, added in Unicode 15.1 with 622 characters; Unicode 17.0 followed with Extension J, another 4,298.
How many Chinese characters does Unicode have?
The honest answer is a number plus a version. As of Unicode 16.0 the ten blocks above contain 97,668 assigned ideographs, and the total climbs with nearly every release because the Ideographic Research Group keeps encoding newly attested characters. The question is also fuzzier than it looks. The unified blocks hold characters used for Chinese, Japanese kanji, Korean hanja and Vietnamese chữ Hán, all sharing the same repertoire. CJK radicals (U+2E80..U+2EFF) and CJK strokes (U+31C0..U+31EF) are components, not ideographs, so they stay out of the count. And roughly a thousand CJK compatibility ideographs duplicate unified characters purely for legacy round trips. Quote any figure without its Unicode version and it will be wrong next year.
Gotchas that break real code
Fullwidth forms. The Halfwidth and Fullwidth Forms block (U+FF00..U+FFEF) contains a second copy of ASCII: A is U+FF21 FULLWIDTH LATIN CAPITAL LETTER A, a different code point from U+0041. Input from a Japanese IME often arrives this way, so a form field can hold 123 where the backend expects 123. The UCD records a wide-variant decomposition for each of these, and NFKC normalization folds them back to plain ASCII.
Halfwidth katakana. U+FF61 through U+FF9F are the single-byte-era katakana from JIS X 0201, for example カ, HALFWIDTH KATAKANA LETTER KA. They still surface in old Japanese data, and NFKC maps them to the normal katakana (カ, U+30AB).
CJK punctuation lives in its own block. 、 is U+3001 IDEOGRAPHIC COMMA, 。 is U+3002 IDEOGRAPHIC FULL STOP, and the corner brackets 「」 sit alongside them in CJK Symbols and Punctuation (U+3000..U+303F). Their script property is Common, not Han. A regex like [\u4E00-\u9FFF], often pasted around as the way to match Chinese characters, matches none of this punctuation and misses about four fifths of the encoded Han repertoire too.
The ideographic space breaks naive tokenizers. U+3000 IDEOGRAPHIC SPACE is a full-width space separator used in CJK text, and splitting on the ASCII space does not see it:
"a b".split(" ") // ["a b"], no split happened
/\s/.test(" ") // true, U+3000 is WhiteSpace
"a b".split(/\s+/) // ["a", "b"]
"123".normalize("NFKC") // "123"
"豈".normalize("NFC") // "豈"Compatibility ideographs are the last trap. The block CJK Compatibility Ideographs (U+F900..U+FAFF) exists so legacy encodings round-trip, and its entries are canonically equivalent to unified ideographs. U+F900 has a canonical decomposition to U+8C48 豈, so NFC normalization silently rewrites it, as the last line above shows. A value stored before normalization will fail an equality check against the same value stored after.
Working with CJK text
- When text misbehaves, look at the real numbers first. Paste it into the converter and use Inspect on the Characters panel for names, blocks and scripts.
- Do not treat U+4E00..U+9FFF as all Chinese characters. Match the Han script property where your regex engine supports it, or include the extension ranges.
- Normalize before comparing, deduplicating or hashing: NFC for canonical equivalence, NFKC when fullwidth input should collapse to ASCII.
- Tag the language of CJK content (
zh-CN,zh-TW,ja,ko) so browsers pick the regionally correct glyph forms for the unified code points.
If the notation in this article is still unfamiliar, What is Unicode? covers code points, planes and blocks from the ground up.
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