HTML Minifier & Beautifier

Global tools

Paste a page or a fragment and this tool gives you the smallest version that still renders the same way - or, the other way round, the same markup laid out one block element per line so a human can read it. Every byte it removes is counted and named, so the result comes with its own audit: how many comments went, how many runs of whitespace, and which regions were copied through untouched.

Paste a whole page or a fragment and nothing is truncated. The page starts from a small sample you can replace.

Minifying removes what is not rendered; beautifying changes only the layout, never the contents.

`<!--! ... -->` comments are the license convention and `<!--[if ...]>` comments gate old browsers, so both stay unless you say otherwise.

Leave it blank and the name is built from the page: "page.html", "page.min.html".

Results update as you type. Nothing leaves your device.

Minified HTML

-18.3%

339 B became 277 B: 0 comments and 22 runs of whitespace went, while 1 protected region (<pre>) were copied through byte for byte. Everything else is as it was written.

Input
339 B
Output
277 B
Saved
62 B
Comments out
0

Minified HTML

<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Sample page</title></head><body><main class="wrap"><!--! danfio sample page --><h1>Hello</h1><p>A paragraph with <a href="/">a link</a> and some text.</p><pre>  keep   this   spacing  </pre></main></body></html>

Copy it, or download it. The bytes in the box are the bytes in the file.

What changed, by name and by count

WhatHow manyNote
Comments removed0every `<!--!` banner and conditional comment kept
Runs of whitespace collapsed22never inside a string, pre, textarea, script or style
Regions copied byte for byte1<pre>

The counts are what this pass actually did rather than what it might have done, which is the whole reason for printing them.

What was deliberately not done

  • Nothing is removed: no element, no attribute, no quotes, no optional closing tag. The self-closing slash survives too, because inline SVG needs it to end an element.
  • `pre`, `textarea`, `script` and `style` are copied byte for byte, so a stylesheet inside a page is left alone and a script is never minified by accident.
  • Whitespace is dropped only beside a block-level element; beside anything this page cannot classify it is kept, which costs a byte and never changes a layout.
  • The one thing it cannot see: an element you styled `white-space: pre-wrap` renders its whitespace, and nothing in the text says so. Wrap such content in `pre` if the difference matters.

A minifier for HTML is a question of what a browser would render, which is why this one works token by token rather than with a pile of regular expressions. Whitespace is dropped only beside a block-level element, where a browser would not draw it; `pre`, `textarea`, `script` and `style` are copied word for word, because inside them whitespace and punctuation are content; and a page whose tags do not balance is refused with a caret at the trouble instead of being half-processed. Each of those rules is named again in the list under the result, so you can check the output against the page’s own promises instead of trusting a magic box.

About this html formatter & minifier

This page is the HTML half of the minifier pair, and it stops where the pair stops: nothing is removed except comments and the whitespace a browser would not render, and nothing is rewritten that could change what the page does. There is no minification of the JavaScript inside a ` <script>` - that block is copied through word for word, because shrinking it is the kind of work that needs a full JavaScript reader and belongs to a real minifier. If the honest limit matters to you, the page prints it under every result.

Everything happens in the tab: the text is read, rewritten and measured by JavaScript on the page, and the only files that leave the computer are the ones you download on purpose. The static page already carries a real minified page computed for the page from the sample, so it is still useful with JavaScript switched off. If you came for the other half, the CSS tool is one click away and shares the same calculation, the same count table and the same honesty about what it will not touch.

How this html formatter & minifier works

What a minifier may delete without asking

Two things go, and only two: comments and harmless whitespace. A comment is dropped unless it starts `<!--!`, which is the convention for a license banner, or is one of the `<!--[if ...]>` conditional comments written for old browsers - both stay by a switch that defaults to keeping them. Whitespace is collapsed to one space and then dropped wherever a browser under `white-space: normal` would not render it: at the start or end of the page, or beside a block-level element such as a `div`, `p`, `ul` or `h1`. Beside anything the pass cannot classify it is kept, because the cost of a wrong guess is a layout that silently shifts.

Everything else is left exactly as written. No attribute is reordered, no quotes are removed, no optional closing tag is added, no self-closing slash is touched - inline SVG needs that slash to end an element - and no element is merged. The output is deliberately of a kind you can diff against the input and understand.

The four elements a careless minifier breaks

`pre`, `textarea`, `script` and `style` hold text where every space and every newline means something, so their contents are copied word for word. A stylesheet inside a `<style>` block keeps its own formatting and is never minified by accident, and a `<script>` block survives untouched for the reasons the page states - minifying JavaScript needs a full reader, and a tool that only ever sees the page cannot guess where a template literal ends.

The same byte-for-byte rule protects the self-closing slash in inline SVG, because there the slash is how an element ends. Protecting these five regions is what makes the minifier safe to run on an unvisited page: the places where whitespace matters are known by name rather than hoped for.

Where whitespace is load-bearing, and where it is decoration

The rule is the one a browser applies under `white-space: normal`: a run of whitespace is kept as one space when both neighbors are inline, and dropped beside a block-level element, at the start of a block or at the end of one. That is why `<p>Hello <b>world</b></p>` keeps the space between the text and the bold word while the spaces around the `<p>` itself go.

The honest limit is on the page’s own list: an element you styled with `white-space: pre-wrap` renders its whitespace, and nothing in the text says so. The pass treats unknown and inline elements conservatively, so such a page comes out safely slightly larger rather than visibly broken - wrap pre-rendered content in `pre` if the difference matters.

The beautify direction: the same file, laid out for a human

The other direction removes nothing and changes nothing but the layout: one block element per line, indentation for nesting, and inline content left on its own line. Comments stay where they were, attribute spacing is tidied, and every tag, attribute and value is exactly as written - a page that a diff can work with and a person can read.

Beautifying is not a claim about anyone’s original formatting, because nobody can recover the line breaks another author chose. It is simply the same document re-spaced by the same rules that decide which whitespace matters, which is why both directions share one notion of where whitespace exists at all.

Worked examples

Each example below was run through the calculator on this page when the site was built, so the numbers match what you see when you enter the same inputs.

A small page, minified

Paste your HTML: <div> <p>Hello <b>world</b></p> </div>

Minified HTML

-10.0%

40 B became 36 B: 0 comments and 3 runs of whitespace went, while 0 protected regions (none found in this page) were copied through byte for byte. Everything else is as it was written.

Input: 40 B · Output: 36 B · Saved: 4 B · Comments out: 0

The indentation around the block elements goes, and the space between the text and the bold word stays.

A banner and a protected element survive

Paste your HTML: <!--! (c) 2026 --> <main> <pre> keep this spacing </pre> </main>

Minified HTML

-6.9%

72 B became 67 B: 0 comments and 3 runs of whitespace went, while 1 protected region (<pre>) were copied through byte for byte. Everything else is as it was written.

Input: 72 B · Output: 67 B · Saved: 5 B · Comments out: 0

The license banner is kept by default and the `<pre>` block is copied word for word.

Beautified instead of minified

Paste your HTML: <header><h1>Hi</h1></header><p>Text</p> · Direction: Beautify - lay it out for a human to read

Beautified HTML

5 lines

39 B became 45 B. Nothing was removed - every tag, attribute and value is still there; only the layout changed.

Input: 39 B · Output: 45 B · Comments kept: 0 · Values changed: none

The same markup, one block element per line, nothing removed.

Frequently asked questions

Is my HTML uploaded anywhere?

No. The text is read, rewritten and measured by JavaScript in this tab, the results panel is built from what is already on the page, and the download is a blob created locally. A page is often an email, a template or a component of a product, so nothing here touches a server at all.

Why is the content of `<pre>`, `<script>` and `<style>` left alone?

Because inside those elements whitespace and punctuation are content, not layout. A `<pre>` block is whitespace a browser really renders, a stylesheet is not markup to be re-spaced, and a script is code whose meaning an HTML minifier cannot be allowed to guess at. They are copied word for word, and the results panel counts them as protected regions.

Does minifying change anything a visitor sees?

No, and that is the point of the boundary. Only comments and whitespace that a browser would not render are removed, so the rendered page is identical in every browser that follows the same whitespace rules. The page’s own table prints what was removed and what was deliberately left, so the claim is checkable rather than assumed.

Will it shrink the JavaScript on my page?

No, and that is a decision rather than a missing feature. Minifying JavaScript safely needs a full JavaScript reader, and an HTML tool is the wrong place to guess at one - the page simply leaves the `<script>` block as it found it and prints that it did so. Use esbuild, terser or your bundler for the script, and this page for the markup around it.

Can I use it the other way round, to read a minified page?

Yes, and that is the beautify direction. Nothing is removed: the page comes back one block element per line with indentation and inline content on its own line. The output is not a claim about the original author’s formatting - nobody can recover line breaks someone else deleted - but it is a file a human can read and a diff can work with.

Assumptions and sources

  • Tidying follows how browsers treat HTML whitespace: a run becomes one space between inline content and disappears beside a block element.
  • `pre`, `textarea`, `script`, `style` and inline SVG are copied word for word, and a page with unbalanced tags is refused with its line and column.
  • Everything runs in your browser; nothing is uploaded.

Last reviewed 2026-10-07. Runs locally on your device; keep backups; no financial advice applies. Read the full disclaimer.

Where a figure on this page comes from an official agency — HUD, IRS, FICO or a state body — the site keeps a dated snapshot of the source page in its sources library, and a scheduled job re-checks that snapshot, so the number can be traced back to the document it came from.