Invisible Unicode Characters: The Complete Reference List
Every invisible or near-invisible Unicode character worth knowing about, what it is for, and whether it is safe to remove.
What counts as an invisible character
An invisible Unicode character is a code point that renders with no visible glyph, or with a glyph so small or so similar to a regular space that it is functionally invisible to a reader. Some exist for legitimate typographic or linguistic reasons — joining letters in Arabic, marking text direction, spacing out digits. Others exist purely as technical artifacts of software, and a few are used deliberately to hide text from human readers while keeping it machine-readable. The table below covers the ones you are most likely to run into, what each is actually for, and whether it is safe to strip on sight.
Reference table
| Character | Code point | Category | Where it comes from | Safe to remove? |
|---|---|---|---|---|
| Zero Width Space | U+200B | Formatting | AI chat UIs, PDFs, web copy | Yes |
| Zero Width Non-Joiner | U+200C | Script control | Persian, Arabic, Indic script rendering | No — required in those scripts |
| Zero Width Joiner | U+200D | Script control | Emoji sequences, Indic script rendering | No — keep inside emoji |
| Word Joiner | U+2060 | Formatting | Rich-text editors, AI chat UIs | Yes |
| Byte Order Mark / ZWNBSP | U+FEFF | Encoding marker | File headers, some text exports | Only legitimate as the first character of a file |
| Left-to-Right Mark | U+200E | Bidi control | Mixed-direction text, some chat UIs | Usually yes, outside bidi text |
| Right-to-Left Mark | U+200F | Bidi control | Mixed-direction text, some chat UIs | Usually yes, outside bidi text |
| LTR/RTL Embedding & Override | U+202A–U+202E | Bidi control | Legitimate bidi text; also "Trojan Source" code attacks | Flag and inspect — security risk |
| Bidi Isolates | U+2066–U+2069 | Bidi control | Modern bidi-aware text rendering | Usually yes, outside bidi text |
| Soft Hyphen | U+00AD | Typography | PDFs and web pages at line-wrap points | Yes |
| No-Break Space | U+00A0 | Spacing | Web pages, word processors, AI chat UIs | Yes — convert to a regular space |
| Narrow No-Break Space | U+202F | Spacing | French typography, some locales | Case by case |
| Figure / Thin / Hair Space | U+2007, U+2009, U+200A | Spacing | Typeset documents, number alignment | Case by case |
| Ideographic Space | U+3000 | Spacing | CJK text and full-width input | No — required spacing in CJK |
| Mongolian Vowel Separator | U+180E | Script control | Mongolian script text | No — required in that script |
| Invisible Separator / Times / Plus | U+2062–U+2064 | Math markup | MathML and technical publishing exports | Yes, outside math content |
| Hangul Filler | U+3164 | Script control | Korean input method placeholders | Case by case |
| Variation Selectors | U+FE0E / U+FE0F | Presentation control | Emoji vs. text presentation switching | No — required for emoji presentation |
| Tag Characters | U+E0000–U+E007F | Deprecated tagging | Flag emoji; also abused for "ASCII smuggling" | Flag and inspect — security risk |
| Private Use Area | U+E000–U+F8FF | Application-defined | Icon fonts, app-specific glyphs | Case by case |
How they get into text
Most invisible characters arrive as a byproduct rather than by intent. AI chat interfaces (ChatGPT, Claude, Gemini) use zero-width characters internally for cursor tracking and streaming, and these leak into copied output. Rich-text editors like Word, Google Docs, and Notion embed formatting metadata as invisible characters. PDF-to-text extraction routinely inserts non-breaking spaces and soft hyphens at line-wrap boundaries. Copying from a web page pulls in whatever non-breaking spaces and joiners the page's CSS and markup relied on for layout. A smaller set — bidi overrides and tag characters — can also be inserted deliberately, either to obscure text from a casual reader or, in security contexts, to smuggle instructions past a filter that only checks visible content.
Why they matter
For search and text matching, an invisible character splits what looks like one word into two tokens, or makes two visually identical strings fail an equality check. For code, they produce syntax errors and reference errors that are nearly impossible to spot by reading the source. For data, they break deduplication, VLOOKUP-style matching, and database joins on values that display as identical. For security, bidi override characters (U+202A–U+202E) can reorder how a line of code displays without changing what it executes — this is the basis of "Trojan Source" attacks — and tag characters (U+E0000–U+E007F) can encode hidden text inside what looks like a single emoji, a technique used in prompt-injection attempts against AI systems.
How to detect them
The raw view on our tools labels every hidden character it finds with its code point, so you see exactly what is in a string instead of guessing. Outside of that, a regex character class targeting specific code points (for example /[\u200B\u200C\u200D\uFEFF]/g in JavaScript) finds them programmatically, and most modern code editors — VS Code in particular — have a Unicode highlighting setting that flags unusual characters as you type.
What GPT Cleanup removes, and what it leaves alone
To be precise about scope: GPT Cleanup removes U+200B, U+200C, U+200D (except inside emoji sequences, where it is kept), U+2060, U+FEFF, U+200E, U+200F, and U+00AD, and it converts U+00A0 to a regular space. It does not currently touch the bidi override and isolate characters (U+202A–U+202E, U+2066–U+2069), the narrow and specialty spaces (U+202F, U+2007–U+200A), the ideographic space (U+3000), the Hangul filler (U+3164), tag characters, or private-use characters. If you are specifically checking for the security-relevant categories — bidi overrides or tag characters — you need to look for them separately; this list is meant to make that easy to do by hand or with a regex.
For a hands-on comparison across the common set, our zero-width space remover strips the categories listed as removable above, and our AI detector scans and reports on the full set found in a given piece of text. For background on why AI chat interfaces specifically leave these characters behind, see our companion post on zero-width characters.