XML Minifier
Strip insignificant whitespace from XML — mixed content, CDATA and preserved subtrees byte-identical, savings measured, entirely on this device.
Mixed content, CDATA and xml:space="preserve" subtrees come back byte-identical — only whitespace, plus whatever you tick below, is removed.
- Deletes <!-- … --> outside mixed content — build notes and licence headers go with them.
- Deletes <? … ?> outside mixed content — dropping <?xml-stylesheet?> stops a browser styling the document.
- Deletes the leading <?xml … ?> — a non-UTF-8 encoding label or standalone="yes" is then no longer stated.
Press ? for shortcuts
Do it offline:$ xmllint --noblanks file.xml
How to use it
- Paste XML or drop a file — .xml, .svg, .rss, .plist and .wsdl all count; past 2 MB the run button names the size first.
- Leave the three removal switches off for a pure whitespace pass, or enable comment, PI and declaration removal one at a time.
- The status line names original size, minified size and percentage saved, plus the gzipped weight where the browser can measure it.
- Copy the line, download a UTF-8 .xml file, or share the state as a link.
An XML document that a human formatted carries indentation a parser never reads. This page removes exactly that — the whitespace between elements — and reports what you saved in bytes. Text you can see, CDATA sections and any subtree marked to keep its spacing come back unchanged, and nothing is uploaded: the document is minified here, on this device.
Examples
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<price>44.95</price>
</book>
</catalog><?xml version="1.0" encoding="UTF-8"?><catalog><book id="bk101"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><price>44.95</price></book></catalog>The savings line reads 197 B → 174 B · saved 11.7%. Only indentation left; the declaration keeps its bytes, and a chip reports “3 mixed-content regions kept byte-identical” because each leaf element holds text.
<page>
<p>Hello <b>world</b>!</p>
<query><![CDATA[SELECT * FROM t WHERE a < 3]]></query>
</page><page><p>Hello <b>world</b>!</p><query><![CDATA[SELECT * FROM t WHERE a < 3]]></query></page>Both children return exactly as pasted — 100 B → 93 B · saved 7%, all of it document-level line breaks. The space after Hello is character data and a CDATA section is text, so neither span can be collapsed.
<config>
<!-- staging credentials live in vault -->
<host>eu-1.internal</host>
<note>Retry <em>twice</em> <!-- product decision --> before paging.</note>
</config><config><host>eu-1.internal</host><note>Retry <em>twice</em> <!-- product decision --> before paging.</note></config>With comment removal on, the readout is “1 comment removed” and “1 comment kept in mixed content or an xml:space="preserve" subtree — those regions are never edited”: 169 B → 117 B · saved 30.8%. The survivor sits between words, where deleting it would edit content.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
Where the removable bytes actually are
Only the gaps between tags can go, so a deep configuration file of short values sheds much of its size while a document that is mostly prose barely moves. The percentage is measured in UTF-8 bytes, not characters — an emoji in a value counts as four.
A subtree marked xml:space="preserve" is a hard stop
Whoever wrote the document declared that whitespace meaningful, so every byte inside survives and the reported saving accounts for it. In this first version a nested xml:space="default" does not turn collapsing back on below it: the marked subtree ships as pasted.
What removing a declaration or a stylesheet PI costs
Dropping <?xml version="1.0" encoding="ISO-8859-1"?> takes the encoding label with it, and a consumer that trusted the label now assumes UTF-8; standalone="yes" is lost the same way. A warning states each fact as it happens. A <?xml-stylesheet?> instruction is what renders the file in a browser — remove it and the page stops styling itself.
Minify or gzip: measure before you choose
A 13.8 KB indented event log falls to 11.9 KB here, 14% saved — yet gzipped the two versions weigh 1.0 KB and 1018 B, roughly 2% apart. Repeated indentation is what a compressor encodes for almost nothing, so the raw figure overstates what the wire notices. Minify for parsers and quotas; compress for transport.
Already-minified input, byte-order marks and CRLF
When output matches input byte for byte the status line says so rather than printing a zero-percent gain. A leading byte-order mark is counted in the original size and removed with a notice; CRLF breaks are measured as the two bytes they are, so a Windows file reports a larger saving than the same document with LF.
Common errors
Closing tag '</config>' at line 1, column 16 — '<item>' opened at line 1, column 9 is still open; did you forget '</item>'?- Nothing is minified until the whole document parses; the diagnostic names both ends of the broken pair so you can see which level lost its closer.
Bare '&' at line 1, column 9 — probable cause: a literal ampersand; write '&' (entities look like '&name;', ' ' or '😀').- Ampersands start entity references, and this page never expands or repairs one — it reports where the document stopped being XML. Query strings pasted into attributes are the usual source.
Unterminated comment at line 1, column 4 — probable cause: missing '-->'.- The scan ran to the end of the file hunting the closing marker, so the caret points at where the comment opened — a broken comment swallows real markup.
This tool minifies up to 50MB; beyond that, try the CLI: xmllint --noblanks file.xml- Past the limit the answer is a refusal, not a partial pass: half a minified document is not the same document. The xmllint binary ships with macOS and most Linux distributions.
FAQ
Can minifying change what my XML means?
No. Whitespace disappears only from the gaps between elements, where it carries no information; every other byte is copied across. The switches that delete markup are off unless you turn them on, and each reports what it took.
The XML Formatter has a Minify tab — why use this page?
Same whitespace pass, more instrumentation: the byte and gzip readout, three optional removal switches with their counts, and a windowed view for output too long to render at once. Reach for the formatter when you want the document readable again.
Should I minify XML, gzip it, or both?
Both, in that order, but expect the second step to do most of the work: on the measured example above the gzipped difference lands near 2%. Minification pays off where bytes are counted before compression — message size limits, database columns, signed payloads.
Is it safe to strip comments from a production file?
Usually, with two caveats: some toolchains hide directives in comments, and a comment sitting inside text is deliberately left alone, so the removed count can be lower than the number you counted. Compare both figures before shipping.
Keyboard shortcuts
- ⌘/Ctrl + Enter
- Minify now — mandatory past 2 MB.
- ⌘/Ctrl + S
- Save the minified line as a .xml file.
- ⌘/Ctrl + C
- Copy the whole result with nothing selected.
- ⌘/Ctrl + Shift + C
- Force-copy everything despite a selection.
- t
- Change theme while no pane is being typed in.
- ? or ⌘/Ctrl + /
- Show this binding list in an overlay.
- Esc
- Close the top dialog; your paste stays.