Free HTML formatter and beautifier. Pretty-print and indent HTML, or minify to remove whitespace and comments. Quote-aware, handles void tags. No upload.
Paste HTML into the box on the left and the formatted result appears on the right immediately — there is no "Format" button to press and nothing is uploaded. The whole tokenizer and printer run as JavaScript in your own browser tab, so build output, page source containing customer data, or a template you are not allowed to paste into a third-party service can all be reformatted without leaving the machine.
Two modes share the same parser. Beautify puts each element on its own line and indents by nesting
depth, using 2 spaces, 4 spaces, or a tab — whichever you pick from the Indent menu. Minify
removes the line breaks and indentation again, drops comments, and gives you a single line. The counter above the
panes tells you which happened: Beautified 47 tokens, or
Minified 1,204 → 968 chars (−236).
A bundler, a template engine, or a "view source" on a production page hands you one enormous line. Nothing is wrong with it — browsers do not care — but you cannot find the element you are looking for. That is what Beautify is for. The tool's own sample input is exactly this case:
<!DOCTYPE html><html><head><title>Demo</title><meta
charset="utf-8"></head><body><nav class="main"><ul><li><a
href="/?a=1&b=2">Home</a></li>…
Beautified with 2-space indent, that becomes a nested outline: <html> at column 0,
<head> and <body> one level in, <title>Demo</title>
collapsed onto a single line because it is a tag containing nothing but text, and <meta charset="utf-8">
sitting flat rather than opening a level of its own. Minifying the same sample goes from 297 characters to 279 —
a small saving, because the only removable material is the HTML comment and the whitespace between tags. That ratio is
worth internalising before you reach for minification as a performance fix: on real pages the wins come from
compression and from the assets, not from the angle brackets.
| Token | Beautify | Minify |
|---|---|---|
| Tags and attributes | Kept byte-for-byte, then indented | Runs of whitespace inside the tag collapse to one space |
| Text between tags | Whitespace collapsed, placed on its own line | Whitespace collapsed to one space |
| Whitespace-only text | Dropped | Dropped |
<!-- comments --> | Kept, on their own line | Removed |
<!DOCTYPE> | Kept verbatim | Kept verbatim |
Void tags (<br>, <img>…) | Own line, no extra indent level | Kept |
Bodies of script, style, pre, textarea | Emitted verbatim, unindented | Emitted verbatim, byte-for-byte |
A naive indenter treats every opening tag as a level and every closing tag as a level back — then meets
<br> or <img>, never sees a matching close tag, and marches the rest of the
document off the right-hand side of the screen. HTML's void elements have no closing tag by definition, and this
formatter knows all of them: area, base, br, col,
embed, hr, img, input, link, meta,
param, source, track, wbr. Each one is printed on its own line at
the current depth and the depth is left alone. Explicitly self-closed tags — anything ending in
/>, which is how inline SVG is usually written — are treated the same way, so
<path d="M0 0"/> inside an <svg> block does not derail the indent either.
The tag scanner is quote-aware, which matters more often than people expect. A > inside an
attribute value — title="a>b", or a comparison operator inside an inline handler — does
not end the tag early, because the scanner tracks whether it is inside a " or ' string
while it looks for the closing bracket.
pre, textarea, script, styleEverywhere else in an HTML document, a run of spaces, tabs, and newlines renders as a single space, so a formatter
can move things around freely. Inside four elements it cannot. <pre> and
<textarea> render their whitespace literally — re-indenting them visibly changes the page,
adding leading spaces to every line of a code sample or silently editing a form's default value.
<script> and <style> hold raw text rather than markup at all, and a
< inside them (if (a < b)) is a less-than sign, not the start of a tag.
This tool captures the body of all four verbatim, from the opening tag to the matching close tag, and never touches
the contents. In Minify mode the bytes come through exactly as they went in — your <pre>
block keeps its trailing spaces and internal newlines. In Beautify mode the body is emitted at its original column
rather than re-indented, with one small exception worth knowing: a leading newline and any trailing whitespace on the
block are trimmed. If you need a byte-identical round trip of a <pre> block, use Minify.
This is the one behaviour that genuinely changes how a page looks, and it is worth ten seconds of attention because it bites in both directions.
Beautify puts adjacent inline tags on separate lines. Give it
<p><span>a</span><span>b</span></p> and each
<span> lands on its own indented line. The newline and indentation are whitespace, and a browser
renders whitespace between inline elements as a space — so what read as ab now reads as
a b. On flowing prose that is invisible and harmless. On a run of inline-block cells, an icon sitting
flush against a label, or digits joined to a superscript, it is a real one-space shift in the layout.
Minify drops whitespace-only text nodes entirely. The mirror image:
<span>a</span> <span>b</span> minifies to
<span>a</span><span>b</span> and the words run together. Note the precise rule
— a text node that is only whitespace is removed, while a text node with any content keeps one space at
each end. That is why <p>10 <sup>3</sup> m</p> survives minification unchanged
(the spaces belong to the text nodes 10 and m) while a lone space between two
tags does not.
If a gap between inline elements is load-bearing, express it in CSS with margins or gap rather than relying on a whitespace text node, and neither mode can move it.
Minify collapses whitespace runs inside a tag to a single space. That is what turns a tag whose attributes are
spread over five lines back into one line, and it is usually exactly what you want. It also means that whitespace
inside a quoted attribute value is collapsed: title="a b" comes out as
title="a b". Attribute values are single-line text almost all the time, so this rarely surfaces —
but if you keep a multi-line JSON blob in a data- attribute, or a content= meta description
with deliberate double spacing, check that attribute after minifying.
Everything else about your tags is left alone. Attribute order is preserved. Quoting style is preserved —
src=x stays unquoted and single quotes stay single. Tag and attribute case is preserved, so
<DIV CLASS="a"> does not become lowercase. Entities are never rewritten: &
stays & and &b=2 in a query string is not "helpfully" escaped. Boolean
attributes are not shortened, redundant attributes are not stripped, and no tag is ever removed for being optional.
This is a whitespace-and-comments minifier, not an HTML optimiser in the mould of the aggressive build-time tools, and
the output is markup you can still recognise as yours.
HTML is the most error-tolerant format in common use, and this formatter matches it: there is no error panel,
because it never rejects input. It tokenizes what is there and prints it. That is a feature when you are formatting a
fragment — a snippet with a stray </div>, a partial template, a chunk copied out of the
middle of a page — and it means you never have to make a fragment well-formed just to read it.
The cost is that structural mistakes show up as indentation rather than as a message. Unclosed containers are the
common case: <div><p>one<p>two</div> keeps stepping right, because each
<p> opens a level that nothing closes. Browsers apply implied end tags here and would treat the two
paragraphs as siblings; the formatter does not, and shows you the nesting you literally wrote. If beautified output
drifts steadily rightward down the page, read that as a diagnosis: you have an unclosed element above the point where
the drift starts. The same applies in reverse — a surplus close tag pulls the following content out to the left.
If you need something that judges your markup rather than just re-indenting it, an HTML validator is the right tool;
this one only reports what it sees.
Handlebars, Jinja, Liquid, ERB and friends are not HTML, but their delimiters are just text as far as the tokenizer
is concerned, so they pass through unharmed. {{#each items}}, {% if user %} and
{{ user.name }} come out identical — each on its own line when beautified, back inline when
minified. What the formatter will not do is understand them, so a {% if %} that opens a
<div> in one branch and not in the other will indent according to the literal tags in the file.
Legacy conditional comments are the one construct minification deletes outright. <!--[if IE]>…<![endif]-->
is syntactically an HTML comment, so it is removed along with the rest. If you are still shipping one, minify around it
rather than through it.
If the markup you are cleaning up is really a data payload rather than a page, the XML formatter is the closer fit — XML is strict where HTML is forgiving, and it reports the parse errors that this tool intentionally does not.
They refer to the same thing. "HTML formatter" and "HTML beautifier" both describe re-indenting and pretty-printing HTML so the nested structure is easy to read. This tool does that in beautify mode and also offers a minify mode that goes the other direction by stripping whitespace and comments.
No. Beautifying only adds or normalizes whitespace between tags, and browsers ignore insignificant whitespace, so the rendered page looks the same. Minifying removes whitespace and comments while preserving the single spaces that inline content needs, so the visible result is also unchanged.
No. The entire formatter runs in your browser using JavaScript. Your markup never leaves your device, which makes it safe to format proprietary templates, client work, or anything confidential.
No. The contents of script, style, pre, and textarea elements are treated as raw text and preserved exactly as written, so JavaScript containing comparison operators or strings, and CSS inside style blocks, are never reflowed or corrupted.
Yes. The tokenizer is quote-aware, so a greater-than or less-than character inside a quoted attribute value does not prematurely close the tag. This is a common failure point for regex-based formatters that this tool avoids.
Beautify CSS into clean, indented rules with one declaration per line, or minify it to strip whitespace and comments. Handles nested at-rules and runs in your browser.
Beautify, indent, and minify XML with live validation — all in your browser.
Format, validate, and beautify JSON data with syntax highlighting and error detection