Zero-Width Characters: The Invisible Text in Your Documents

· 2 min read

Zero-width characters are Unicode code points that take up no visible space in rendered text. They influence how text is shaped, broken, and joined without producing a visible glyph. Used correctly, they're essential tools for internationalisation. Used maliciously, they're a favourite trick for hiding data, bypassing text filters, and spoofing identities.

The Main Zero-Width Characters

  • U+200B Zero-Width Space (ZWSP): Marks a legal line-break opportunity without rendering a visible space. Useful in long unbreakable strings like URLs or CJK text.
  • U+200C Zero-Width Non-Joiner (ZWNJ): Prevents two adjacent characters from forming a ligature or joining form. Critical in Arabic, Persian, and Indic scripts.
  • U+200D Zero-Width Joiner (ZWJ): The opposite—forces characters to use their joining form, and is used in emoji sequences (e.g., family emoji) to combine multiple emoji into one glyph.
  • U+FEFF Byte Order Mark (BOM): At the start of a file, signals the byte order of a UTF-16 stream. In UTF-8 it carries no meaning but is sometimes inserted by Windows editors, confusing parsers that don't expect it.
  • U+2060 Word Joiner: Prevents a line break at its position, similar to a non-breaking space but invisible. A better alternative to the BOM in that role.

Security Implications

Zero-width characters are invisible to the naked eye but present in the underlying text. Attackers use them to create strings that look identical to a target string but are technically different—bypassing blocklists, poisoning copy-pasted code, and creating look-alike domain names. A password policy that "bans the word password" won't block p​assword.

They're also used to watermark documents: by encoding a hidden bit pattern of ZWSPs and ZWNJs, you can identify which recipient leaked a confidential document. See the full list of zero-width and formatting characters at the zero-width characters reference page.

Detecting Hidden Characters

Most text editors don't render zero-width characters, so they're effectively invisible in normal editing. To detect them, use a tool like CharLookup search—paste text containing hidden characters and each code point will be revealed. Alternatively, check the raw byte representation: zero-width characters have their own specific byte sequences in UTF-8.