Skip to content
Ghostchars

What Ghostchars detects

Every category the engine can report, the option that governs each, and the codepoints with a page of their own. This is the reference; the tool is on the home page.

Removed by the default passKept when load-bearingNeeds an option

By category

Categories are tested in this order and the first match wins, which is why a zero width space is reported as a zero-width character rather than as a generic format control.

Zero-width and invisible

Governed by Default pass (always on)

Characters with no glyph and no width that are contraband anywhere in prose: zero width space, word joiner, soft hyphen, the byte order mark, the four invisible maths operators, deprecated format controls, interlinear annotation marks, musical-notation controls and Unicode’s permanently reserved noncharacters.

Bidirectional marks

Governed by Bidi marks --bidi

Direction hints — the left-to-right and right-to-left marks, the Arabic letter mark, and the four isolates. Next to right-to-left text they resolve genuine ambiguity and are kept; in an English paragraph they are invisible padding and a published steganography carrier, and they go.

CodepointNameDefault pass
U+200ELEFT-TO-RIGHT MARKWhen free-floating
U+200FRIGHT-TO-LEFT MARKWhen free-floating
U+061CARABIC LETTER MARKWhen free-floating
U+2066–U+2069BIDIRECTIONAL ISOLATESWhen free-floating

Joiners, selectors and fillers

Governed by Aggressive -a

Invisible characters that bind to the character before or after them: zero width joiner and non-joiner, variation selectors, tag characters, and the script-specific fillers of Mongolian, Khmer and Hangul. Kept when their neighbours make them load-bearing, removed when they are free-floating.

CodepointNameDefault pass
U+200DZERO WIDTH JOINERWhen free-floating
U+200CZERO WIDTH NON-JOINERWhen free-floating
U+FE00–U+FE0FVARIATION SELECTORSWhen free-floating
U+E0000–U+E007FTAG CHARACTERSWhen free-floating
U+180B–U+180DMONGOLIAN FREE VARIATION SELECTORSWhen free-floating
U+17B4–U+17B5KHMER INHERENT VOWELSWhen free-floating
U+115F–U+1160HANGUL JAMO FILLERSWhen free-floating

Any other format control

Governed by Default pass (always on)

The catch-all. Every remaining character whose Unicode general category is Cf is removed, so a format control added in a future Unicode version is caught without a code change. The orthographic exceptions — the Arabic number signs, the Syriac abbreviation mark, the Kaithi number sign — are matched earlier and left alone.

Detected by Unicode property rather than from a list, so there is no fixed set of codepoints to enumerate.

Private-use characters

Governed by Private-use characters --pua

Codepoints Unicode will never assign, whose meaning is a private agreement between a font and an application. Icon fonts live here, which is why removing them is opt-in: in UI copy they are the content.

CodepointNameDefault pass
U+E000–U+F8FFPRIVATE USE AREANo

Line separators

Governed by Line endings -n

Unicode’s line and paragraph separators and the EBCDIC-derived NEL. Folded to a plain line feed rather than deleted — deleting them would run two lines together.

CodepointNameDefault pass
U+2028LINE SEPARATORNo
U+2029PARAGRAPH SEPARATORNo
U+0085NEXT LINENo

Control characters

Governed by Control characters --controls

The C0 and C1 control codes, excluding tab, line feed and carriage return. Their presence in text usually means a decoding accident or a deliberate probe.

CodepointNameDefault pass
U+0000–U+001FC0 CONTROL CHARACTERSNo
U+0080–U+009FC1 CONTROL CHARACTERSNo

Typographic punctuation

Governed by Punctuation --punct

Curly quotes, em and en dashes, the ellipsis, the minus sign and the primes. Nothing is hidden here — these are visible characters — but they are a different codepoint from their ASCII forms, and the straight-versus-curly choice is a published one-bit-per-apostrophe channel.

CodepointNameDefault pass
U+2014EM DASHNo
U+2019RIGHT SINGLE QUOTATION MARKNo
U+2026HORIZONTAL ELLIPSISNo

The options

The default pass needs no option and is always on. Everything else is off until you turn it on, and every one of them changes text you can see — which is exactly why it is off.

OptionCLI flagWhat it doesWhy it is not the default
Default pass(always on)Zero-width characters, the byte order mark, soft hyphens, invisible maths operators, bidi overrides, free tag characters, free variation selectors, noncharacters, every remaining Cf format control, and free-floating glue.Always on. Nothing it removes is visible or load-bearing.
Aggressive-aRemoves glue even where it is load-bearing.Breaks family emoji, Persian and Indic spelling, subdivision flags and CJK glyph variants.
Spaces-sReplaces no-break and exotic spaces with an ordinary space.A no-break space is usually doing its job — French punctuation, "10 km", CJK layout.
Line endings-nFolds CRLF, CR, NEL, U+2028 and U+2029 to a plain line feed.Changing line endings changes the file, and some pipelines depend on them.
Bidi marks--bidiRemoves direction marks and isolates even next to right-to-left text.Breaks the layout of mixed Hebrew, Arabic and Persian text.
Control characters--controlsRemoves C0 and C1 controls, keeping tab and the line breaks.Rare in ordinary text, and their presence usually points at an encoding problem worth fixing at the source.
Private-use characters--puaRemoves codepoints from the private-use areas.Icon-font glyphs live there; removing them empties your interface labels.
Punctuation--punctConverts em and en dashes, curly quotes, the ellipsis and the minus sign to ASCII.It is typography, not hiding. Converting it makes prose worse, not more human.
Lookalike letters--confusablesMaps 1,513 lookalike codepoints to their Latin twins.It destroys real Cyrillic, Greek, Armenian and Cherokee text, and Turkish dotless i.

Whole-text options

Four more options rewrite patterns rather than individual characters, so they have no category of their own.

Normalize (NFC)

Composes a letter and its accent into one codepoint.

It changes bytes that are already correct, and it defeats normalisation-form steganography only when you ask for it.

--nfc

Normalize (NFKC)

NFC plus styled mathematical letters, ligatures and fullwidth forms folded to plain equivalents.

Lossy: 𝐛𝐨𝐥𝐝 becomes bold and the styling is gone for good.

--nfkc

Trailing whitespace

Removes spaces and tabs at the end of every line.

Two trailing spaces are a hard line break in Markdown.

--trailing

Collapse spaces

Collapses runs of spaces inside a line to one, keeping indentation.

Some formats — aligned tables, ASCII art, code — depend on the runs.

--collapse

Every character with a page

Each of these has its own page: what it is, where it comes from, when it is legitimate, and the honest answer to whether it is an AI watermark.

Browse the character index

Questions

How many characters does it detect?

The tables name several hundred codepoints exactly, and two catch-all rules cover every remaining format control and every private-use codepoint by Unicode property — so a character added in a future Unicode version is detected without a code change. On top of that the lookalike map covers 1,513 codepoints.

Is the default pass safe to run on anything?

It is designed to be: the default pass only removes characters that are invisible AND not doing a job in their context. It leaves every visible character alone, including no-break spaces, curly quotes and em dashes. If you want those changed you have to ask.

What if my character is not listed here?

Paste the text into the tool and reveal it. Anything the engine classifies is reported with its position, codepoint, Unicode name and category, whether or not it has a page here.