The basics
What zero-width characters actually are
A zero-width character is a real codepoint that renders with no width and no visible mark. It is not a space you can see and not a gap in the layout, it takes up no room on screen at all, yet it sits in the text between two ordinary letters exactly like any other character would.
That is what makes them a specific kind of trouble. A search, a diff tool or a slug generator reads every codepoint in a string, visible or not, so a zero-width character changes what the machine sees while leaving what a person sees completely untouched.
The characters
The zero-width characters covered in this guide
Four codepoints do this job, and they are worth telling apart rather than treating as one interchangeable problem.
- Zero-width space (U+200B)
- The plain case: it occupies a character slot and does nothing else. The most common of the four in text copied out of a chat interface.
- Zero-width non-joiner (U+200C)
- Normally used to stop two adjacent letters from visually joining into a connected glyph. It has a genuine job in some scripts, covered below.
- Zero-width joiner (U+200D)
- The opposite instruction: join what follows to what came before into one glyph. Its clearest use is building compound emoji.
- Word joiner (U+2060)
- A close relative with a different name. It marks two characters as belonging together without rendering anything, and is usually found wedged against a dash.
Why scanners react
Why scanners flag zero-width characters as AI watermarks
Chat interfaces use zero-width characters as internal bookkeeping: marking where rich-text formatting starts and ends, tracking cursor position through a copy, sometimes just an artefact of how a line was assembled before it reached your clipboard. None of that requires the text to have come from a language model, but AI chat interfaces are a common and repeatable source of it, which is why a scanner built for AI-written text checks for exactly these codepoints.
A scanner flags a codepoint, not an author. It is reporting that a specific invisible character is present at a specific position, which is a fact about the text. What produced the text is a separate question the character alone cannot answer.
The honest part
The legitimate uses zero-width characters actually have
The zero-width joiner is not always residue. It is the character that fuses separate emoji into one compound glyph, a person plus a laptop, a family of four, a flag made of two letters. Strip every zero-width joiner from a message without checking context and multi-part emoji fall apart into their separate pieces.
The zero-width non-joiner does real linguistic work too. In Persian, it separates a prefix or suffix from its stem so the two display correctly without the letters joining, while still reading as one word. In Devanagari, Bengali and several other Indic scripts, it stops two consonants from automatically merging into a single conjunct glyph when the writer wants them shown separately. Neither use is a chat interface leaving a trace behind. Both are the script working as designed.
The fix
How to remove zero-width residue safely in three steps
Blind deletion is the wrong tool here. The goal is removing the residue without removing the characters doing real work.
- 1. Scan before you touch anything
- Paste the text into a scanner that shows each zero-width character by name and position, so you know exactly what is present before changing a single one.
- 2. Check what the flags actually are
- A zero-width joiner sitting between two emoji, or a zero-width non-joiner inside Persian or Indic-script text, is not the same finding as one sitting between two English words for no visible reason.
- 3. Clean the rest
- Remove the zero-width space, the word joiner, and any zero-width joiner or non-joiner that is not doing linguistic or emoji work, and leave the ones that are.
Straight answer
Does a zero-width character prove text is AI-written?
No. These characters turn up in text copied from PDFs, word processors, translation software, and plenty of web pages with no language model anywhere near them. Finding one tells you something was formatted or copied a certain way. It does not tell you who or what wrote the words around it.
Treat a zero-width finding as a formatting fact worth cleaning up, not as evidence to present about a document's origin. The two are genuinely different claims, and only one of them is something a character can support.
Elsewhere
Where else zero-width characters show up
Outside chat interfaces, zero-width characters get used deliberately to split a word across a hashtag without breaking its readability, to slip past a simple keyword filter, or to make two visually identical usernames register as different strings to a system that compares them byte for byte. None of that is about AI text at all, and it is worth knowing this territory exists so a single flagged character does not get over-read as more significant than it is.
Aftercare
What to check after removing them
If the text contains emoji, confirm compound ones still render as a single glyph rather than as separate pictures side by side. If the text is in Persian or an Indic script, read it back and confirm the letterforms still look like the way that language is actually written. A cleaning pass that leaves visible language errors behind has traded one invisible problem for a visible one.