Detect Zero-Width Joiners and Non-Joiners (ZWJ/ZWNJ)

Identify zero-width joiner (U+200D) and zero-width non-joiner (U+200C) characters in text. Understand their role in emoji and scripts.

Zero-Width Characters

Detailed Explanation

ZWJ and ZWNJ: Unicode's Invisible Glue

The Zero-Width Joiner (ZWJ, U+200D) and Zero-Width Non-Joiner (ZWNJ, U+200C) are Unicode formatting characters that control how adjacent characters are joined or separated without adding visible width.

Zero-Width Joiner (ZWJ)

ZWJ is most commonly known for its role in emoji sequences. Modern emoji like family groups, skin tone variations, and profession emojis are created by joining multiple emoji with ZWJ:

👨‍👩‍👧‍👦  =  👨 + ZWJ + 👩 + ZWJ + 👧 + ZWJ + 👦
👨‍💻  =  👨 + ZWJ + 💻  (Man Technologist)

ZWJ is also used in:

  • Indic scripts: Controlling ligature formation in Hindi, Bengali, Tamil
  • Arabic script: Forcing cursive joining between characters

Zero-Width Non-Joiner (ZWNJ)

ZWNJ does the opposite — it prevents characters from joining that would normally connect:

  • Persian/Farsi: ZWNJ separates compound words while keeping them visually close
  • German: Controlling hyphenation behavior
  • Indic scripts: Preventing unwanted ligatures

When ZWJ/ZWNJ Cause Problems

While these characters are legitimate in certain contexts, they become bugs when:

  • Copied into code or variable names
  • Present in JSON keys or values from user input
  • Embedded in URLs or email addresses
  • Causing unexpected string length ("abc".length vs "a\u200Dbc".length)

Visualization

The Whitespace Visualizer shows ZWJ as red [ZWJ] and ZWNJ as red [ZWNJ] markers. The statistics panel counts each separately. You can selectively clean one or both in the Clean section.

Use Case

An internationalization engineer debugging Persian text rendering finds that word boundaries aren't working correctly. They paste the text into the Whitespace Visualizer and discover misplaced ZWNJ characters that were inserted by the content management system, causing incorrect word-break behavior.

Try It — Whitespace Visualizer

Open full tool