PlantUML CJK / Emoji / special-character rendering foot-guns and font setup
PlantUML’s default font DejaVu Sans only ships Latin glyphs. Chinese / Japanese / Korean / Emoji either render as boxes or vanish entirely. This is the font configuration field guide + CI environment setup + multi-language mixing.
Three common symptoms
Symptom 1: Chinese renders as □□□
1 | @startuml |
The SVG shows Chinese as three empty boxes. DejaVu Sans has no CJK glyphs.
Symptom 2: Emoji displays as black-and-white text
1 | @startuml |
Emoji becomes characters like < > instead of colored icons. DejaVu Sans has no Emoji font.
Symptom 3: Japanese kana garbled
1 | @startuml |
Some kana renders, some doesn’t — the font only ships partial Japanese character sets (e.g. only Hiragana, no Katakana).
Fix 1: switch fonts (server / Docker side)
Install CJK fonts on Linux server
1 | # Debian/Ubuntu |
After installing, restart plantuml server to refresh the font cache.
Install fonts inside Docker image
Modify Dockerfile:
1 | FROM plantuml/plantuml-server:tomcat |
1 | docker build -t my-plantuml:cn . |
PlantUML: specify font
1 | @startuml |
Or via CLI:
1 | plantuml -SdefaultFontName="Noto Sans CJK SC" diagram.puml |
Fix 2: Emoji font
Install Noto Color Emoji
1 | # Debian/Ubuntu |
PlantUML configuration
PlantUML uses <fontconfig> for automatic matching, but you must declare intent in the diagram:
1 | @startuml |
Emoji uses Noto Color Emoji, Chinese uses Noto Sans CJK SC. Two fonts coexist, fontconfig falls back automatically.
Foot-gun: PlantUML does not support per-character font switching — if a single line contains both Chinese and Emoji, the Emoji may get rendered by the CJK font (which has no glyph) → Emoji shows as empty box.
Fix — isolate with <font> tags:
1 | Alice -> Bob: <font color=red>🚀</font> deploy success <font color=green>🎉</font> |
Or just separate into multiple lines:
1 | Alice -> Bob: 🚀 |
Fix 3: multi-language mixing
When mixing Chinese / English / Japanese / Korean / Emoji / Arabic / Latin, the font fallback chain is critical.
Linux fontconfig configuration
1 | <!-- /etc/fonts/conf.d/99-cjk.conf --> |
Fonts in <prefer> are tried in priority order: Chinese goes to SC, Emoji to Color Emoji, Latin to DejaVu.
PlantUML multi-font fallback
PlantUML 1.2024+ supports <font> nesting:
1 | @startuml |
Comma-separated font names, PlantUML uses fontconfig to find the first font that can render the glyph.
Fix 4: Mac / Windows local rendering
When rendering locally (e.g. hexo generate with plantuml CLI), fonts must also be installed:
1 | # macOS — PingFang SC is system default |
hexo-renderer-plantuml invokes plantuml which uses <system> fonts by default — macOS uses PingFang, Windows uses Microsoft YaHei, automatically.
CI environment
GitHub Actions default ubuntu-latest has no CJK fonts. Install them:
1 | # .github/workflows/diagrams.yml |
LANG=en_US.UTF-8 makes plantuml use UTF-8 charset — otherwise it may default to ASCII and garble Chinese.
Font subsetting (smaller image)
Full Noto Sans CJK SC is ~20MB. Pushing that into a Docker image is heavy.
Subset to only used characters:
1 | # extract subset with fonttools |
Dockerfile installs subset:
1 | FROM plantuml/plantuml-server:tomcat |
Font size / line-height tuning
CJK character width differs from Latin width — PlantUML’s default line height causes misalignment in mixed text.
1 | @startuml |
Padding 5 makes box inner padding enough for Chinese characters, dpi 150 produces sharper output (default 96).
Debugging flow
1 | # 1. verify fonts installed |
If fc-match returns the wrong font → fontconfig config is wrong. Check the priority of files under /etc/fonts/conf.d/.
Summary
| Scenario | Fix |
|---|---|
| Chinese/Japanese as boxes | Install fonts-noto-cjk, PlantUML specify defaultFontName |
| Emoji displays as text | Install fonts-noto-color-emoji, alongside CJK fonts |
| Mixed CJK/Latin misaligned | Padding 5, dpi 150 |
| CI renders Chinese garbled | apt install fonts + LANG=en_US.UTF-8 |
| Docker image too large | pyftsubset extract the characters actually used by .puml |
| Multi-language mix | fontconfig <prefer> chain, fonts tried by priority |
Minimum setup — install fonts-noto-cjk + fonts-noto-color-emoji on the server, restart plantuml, covers 95% of multi-language needs.
- Title: PlantUML CJK / Emoji / special-character rendering foot-guns and font setup
- Author: puml.online
- Created at : 2026-07-30 16:50:00
- Updated at : 2026-08-14 21:34:29
- Link: https://puml.online/blog/plantuml-cjk-emoji-encoding-en/
- License: This work is licensed under CC BY-NC-SA 4.0.