Before I built MoFont, I assumed Chinese fonts were a finite problem. You write a few hundred characters, the model learns your handwriting style, and it infers the rest — there are only so many common characters going around in circles, right?
Then I learned that "common" Chinese characters number around 6,500, and that the word "common" is a polite fiction. The real trouble isn't inside those 6,500. It's in the long tail that stretches out past them. Every single model I have tested wrecks itself in that tail.
Let's get the numbers straight first
Most people have no intuition for how many Chinese characters there actually are, so let me build the scale with a few standards.
The oldest character set, GB 2312-1980, encodes 6,763 Chinese characters. That's where the colloquial "six-thousand-something common characters" comes from — enough to read the news, send messages, write an essay. Above that, China's Table of General Standard Chinese Characters (2013) contains 8,105 characters, split into three levels: 3,500 common (Level 1), 3,000 secondary (Level 2), and 1,605 (Level 3) — and the official definition of Level 3 is, verbatim, "characters used in surnames and given names, place names, scientific terms, and classical texts in primary and secondary education."
Read that Level-3 wording again: surnames, given names, place names. When the state drafted the standard, it explicitly acknowledged that there is a whole class of characters you will essentially never use — until the moment you need to write a particular person's name or a particular village, at which point that character becomes the single most important one in your life.
Keep climbing. GBK holds over twenty thousand; GB 18030-2005 reaches 70,244 Chinese characters; and Unicode's CJK Unified Ideographs define roughly 102,000 characters as of version 17.0.
So the scale looks like this:
- Daily sufficiency: ~3,500
- The polite meaning of "common": ~6,500
- Full national standard set: 8,105
- What the encoding standards can hold: 70,000 – 100,000+
From 3,500 to 100,000 is nearly a thirtyfold gap. You will personally meet only a handful of the characters in that gap your whole life — but the handful each person meets is different. That is the essence of a long tail: rare in aggregate, essential to the individual.
Why models break precisely in the tail
If you lay out a handwriting model's outputs one by one, a cruel pattern emerges: the more common a character, the prettier it renders; the rarer it is, the blurrier. The everyday workhorses come out crisp from nearly any model. But the moment you hit a character with dense strokes, an unusual radical, or an awkward structure, the strokes start to smear, break, and bleed into each other — sometimes the topology is just wrong, connecting strokes that should be apart and splitting strokes that should join.
The reason isn't complicated, but it is fundamental. Three layers.
Layer one: the training data is itself a long-tail distribution. Any corpus used to train font generation is heavily skewed toward frequent characters. The model has seen the most common ones tens of thousands of times and some rare ones not even once. It knows the strokes of common characters cold and essentially guesses at the tail.
Layer two: few-shot style transfer is fundamentally interpolation. Today's mainstream few-shot font generation does this: you give me a few dozen of your characters, I extract your style (stroke entries, slant, weight, your habits of joining strokes), and I transfer that style onto characters you never wrote. In plain terms, it interpolates among the characters you did write. Common characters render well because their structure closely resembles your samples, so interpolation is stable. The long tail is exactly where interpolation breaks — its radicals, its structure may never appear in your samples at all, the model has no anchor to interpolate from, it can only extrapolate, and extrapolation collapses.
Layer three: complex structure amplifies every error. In a rare character with a dozen-plus strokes, any single stroke that's slightly mispositioned or wrongly weighted turns the dense thicket into mush. Simple characters tolerate error; complex ones tolerate almost none.
This isn't just my private griping; it's an openly acknowledged hard problem in the field. DG-Font states in its paper that font generation is especially challenging for "writing systems with a large number of characters." The later diffusion-based FontDiffuser names "complex characters" outright as a core pain point it set out to solve, engineering a multi-scale content aggregation block specifically to preserve the intricate strokes of complex characters. When an entire research direction publishes papers dedicated to "complex characters render badly," that itself proves the point: the long tail is genuinely hard — no product is just being lazy.
The long tail is the real shippable bar
At this point someone will say: if the tail is so hard, just nail the common characters and call it done? Users spend most of their time on common characters anyway.
It sounds reasonable, and it misses the single most lethal scenario — a person's name.
A font that writes 1,000 common characters with flourish but smears the one rare character in a user's own name is worth, to that user, zero. Not 80%. Zero. Because the first character anyone cares about in a font is almost always their own name, or their child's name. Botch that one and no amount of beauty in the preceding thousand characters can buy it back.
So my stance on the long tail is unambiguous: it isn't a nice-to-have bonus, it's the line between a demo and a shippable product.
A model that only looks good on common characters can produce a screenshot that wows your group chat. A model that holds steady through the tail can export an OTF you actually dare to use. Eighty percent of the gap between a demo and a product lives in that tail. Nailing the frequent characters is table stakes; keeping the long tail from collapsing is the real craft.
If you are here because a specific character in your or your child's name will not render, the practical companion to this post is rare Chinese characters in your own handwriting — it covers what counts as 生僻字, a reference table of the ones that actually appear in names, and how to test a font before buying.
How MoFont answers for the long tail
Back to my own product. MoFont does this: you write about 30–50 characters, I train a complete handwriting font covering 6,500 common characters, export it as both OTF and TTF, deliver in roughly three to four hours, one-time purchase, no subscription.
I'm honest about scope. 6,500 common characters is the range I commit to holding steady — a range I've validated repeatedly by rendering in a real browser, not by fooling myself with cherry-picked generation screenshots. The true long tail beyond 6,500 — deeply obscure classical-text characters, characters that surface only in specific place names — I won't pound my chest and promise every one is perfect. I do what I can do, and where I can't, I'd rather say so plainly than slip you an extrapolation-mangled glyph dressed up as a finished product.
That's my floor on this. The Chinese long tail is a mirror that reveals which fonts were trained in earnest and which are just a model wearing a costume. I'd rather hand you the mirror first than have you discover, the instant you export your font, that your own name came out a blur.
— Iris Gu
