About this whitespace cleaner
A small, dependency-free tool for one job: turning messy pasted text — wrapped lines, doubled spaces, stray blank lines — back into clean text, with six independent options you can combine.
Why it exists
Text arrives from a PDF, an email client, a chat export or a scanned document carrying whatever line-wrapping decision that source made, and none of those decisions are yours. The most common complaint is a paragraph that got hard-wrapped into dozens of one-line fragments, but the underlying problem is broader: extra spaces from justified text, blank lines from a spreadsheet export, trailing whitespace from a code editor. One tool that composes a small set of clear transforms handles all of it without you writing a find-and-replace by hand each time.
How the pipeline is implemented
Six transforms, always applied in the same fixed order regardless of which subset is turned on:
The order is not arbitrary — each choice fixes a real interaction between two options:
- Trim before join. If a wrapped line has leading indentation, joining it into a sentence before trimming would leave the indentation as a stray space mid-sentence. Trimming first removes it cleanly.
- Join before remove-empty-lines. The paragraph-preserving join mode needs the original blank lines to find paragraph boundaries. If empty-line removal ran first, there would be nothing left to mark where one paragraph ends and the next begins.
- Collapse-spaces after join. Joining lines with a single space can itself produce a double space wherever the original line already ended in trailing space. Running collapse-spaces afterwards cleans that up without a separate step.
- Remove-all-whitespace last. It is total by design — whatever the earlier steps left as whitespace, this one removes, so it has to run after everything else to have the final word.
One documented consequence of this order: turning on both “Remove empty lines” and “Keep paragraph breaks” together removes the very blank lines the paragraph join just used as separators, so the paragraphs end up merged after all. That is not a bug — it is what a fixed, predictable order necessarily produces when two options both want the same blank line for different reasons. See the FAQ on the tool page for the worked-through example.
How it was tested
The cleaning pipeline lives in a pure module with no DOM access, so it can run under Node with no browser at all. Before shipping, it was checked against fixed cases including:
- CRLF-delimited and LF-delimited versions of the same text produce byte-identical output for every option combination.
- “Keep paragraph breaks” joins wrapped lines inside a paragraph while a blank-line gap between two paragraphs survives as exactly one blank line, including when the original had three or four blank lines in a row.
- “Collapse multiple spaces” turns a run of mixed spaces and tabs into a single space and leaves newlines untouched.
- “Trim each line” removes leading and trailing whitespace per line without touching blank lines that are supposed to stay blank.
- “Remove empty lines” drops lines that are empty or whitespace-only, and leaves everything else alone.
- “Remove all whitespace” wins regardless of which earlier options also ran.
- Every option combination on an empty string returns an empty string.
All of that runs as a small Node script with zero dependencies, committed at the repository root rather than shipped to visitors.
How the site is built
- Static HTML, one small stylesheet, two small scripts. No framework, no build step, no bundler.
- Nothing is uploaded. The whole transform runs in your browser tab; the text you paste is never sent anywhere and nothing is kept between visits.
- System font stack. Your operating system’s UI font, so nothing has to download and nothing shifts as the page loads.
- Dark mode follows your system setting via
prefers-color-scheme.
Scope and honesty about limits
This is a whitespace and line-structure tool, not a language model. It cannot tell a genuine hyphenated compound apart from a wrap artifact, it does not repair grammar or spelling, and it treats every input as plain text — it has no idea whether what you pasted is prose, a CSV row, or a code comment, so options like “remove line breaks” and “trim each line” are powerful precisely because they do exactly what they say and nothing smarter. Read the option before you click it.