Skip to content
UseQR
ESC

↑↓ MOVE↵ OPEN48 PLACES

Spec & internals

UTF-8 and Unicode in QR codes — emoji, CJK and the legacy trap

QR codes carry Unicode by encoding text as UTF-8 in byte mode — emoji, CJK and accented characters all work on modern phone scanners without an ECI header. The costs: each character takes 1–4 bytes (an emoji is typically 4), and some legacy readers wrongly assume Shift-JIS and show garbled text.

View as MarkdownPaste this page into any AI assistant — it is plain, portable Markdown.

How Unicode gets into a QR code

There is no "Unicode mode". Byte mode stores whatever octets you give it, so the universal recipe is: encode the string as UTF-8, store the bytes, and rely on the decoder to interpret them as UTF-8 — which every current iOS and Android camera does by default. No ECI header needed in practice.

That means a QR code can carry Grüße aus Köln, 東京タワー, مرحبا, or I ♥ QR 🎉 — any Unicode text — subject only to capacity.

What Unicode costs

UTF-8 is variable-width, and QR capacity is counted in bytes, not characters:

Characters UTF-8 bytes each Bits in the symbol
ASCII (URLs, A–Z, digits) 1 8
Latin accents (é, ü, ñ) 2 16
CJK, most scripts 3 24
Emoji (🎉 = U+1F389) 4 32

A 100-character Japanese message is ~300 bytes — the size of a 300-character English one. An emoji costs four times an ASCII letter, and composed emoji (skin tones, families) chain multiple code points: 👨‍👩‍👧 is 18 bytes. Capacity ceilings are byte ceilings — 2,953 bytes at version 40-L is only ~980 CJK characters or ~730 emoji. For dense text, Kanji mode can beat UTF-8 for pure Japanese, at a compatibility price.

The legacy Shift-JIS trap

QR codes were designed at Denso Wave in 1994 for Japanese industry, and the original byte-mode assumption was JIS/Shift-JIS text. Consequences that survive today:

  • Old Japanese-market readers (and some embedded decoders derived from them) interpret unlabelled bytes as Shift-JIS. Your UTF-8 café renders as mojibake.
  • Some decoders sniff and guess wrong on short, ambiguous payloads — a few bytes of accented Latin-1 can also be valid Shift-JIS, and the guess goes to the wrong one.
  • The reverse trap exists too: text encoded as Shift-JIS by a Japanese generator shows garbled on a UTF-8-assuming Western app.

For URLs none of this matters — ASCII is identical in every candidate encoding, which is one more reason payloads that must work everywhere should be a plain ASCII URL with the interesting content behind it.

A real implementation bug worth knowing

Unicode handling is where QR libraries quietly go wrong. A concrete example from UseQR's own stack: the underlying qrcode-generator library's default string handling keeps only the low byte of each JavaScript character code — multi-byte characters are silently mangled. UseQR pre-expands every string into its UTF-8 octets before encoding, so 東京 or an emoji arrives intact. If you use a QR library directly, test a non-ASCII payload and decode the output before trusting it — this class of bug produces codes that look perfect and scan to garbage.

The same caution applies to WiFi passwords and vCards, where special characters meet format-specific escaping rules on top of the encoding question.

FAQ

Can a QR code contain emoji?

Yes. Emoji are encoded as UTF-8 in byte mode — typically 4 bytes each, more for composed sequences — and modern phone scanners display them correctly. They work in text payloads; inside URLs they must additionally be percent-encoded.

Does a QR code support Chinese, Japanese and Korean text?

Yes, as UTF-8 at 3 bytes per character, readable by all current phone cameras. For pure Japanese text, kanji mode stores Shift-JIS characters in 13 bits instead of 24, but with narrower generator and reader support.

Why does my QR code show garbled characters?

Almost always an encoding mismatch: the bytes are UTF-8 but the reader assumed Shift-JIS or Latin-1, or the generator mangled multi-byte characters before encoding. Regenerate as clean UTF-8 and test on the scanners your audience actually uses.

Do special characters make a QR code bigger?

Yes. Any non-ASCII character forces byte mode and costs 2–4 bytes in UTF-8, so accented or CJK text reaches a given QR version sooner than plain ASCII. Capacity limits are counted in bytes, not characters.

Try it — free, no signup