Skip to content

HTML / CSS / JS Minifier and Formatter

Output

Estimates for educational purposes — not financial, medical, or legal advice. See terms.

Minifying and formatting code are mirror operations. Format adds whitespace and newlines so humans can read the structure; minify removes them so machines can transfer fewer bytes. Most code lives in both forms at different times — formatted in the editor, minified in the deployed bundle.

This tool handles HTML, CSS, and JavaScript in your browser. Each language has its own tokeniser tuned to what’s safe to remove and what must be preserved. The implementations are honest about scope: HTML and CSS get full format-and-minify; JavaScript gets a credible whitespace-and-comment minifier and a clear pointer to prettier.io for proper formatting.

What HTML formatting and minification do

Format indents nested elements consistently, with one element per line for block-level tags and inline phrasing kept on the same line as their parent (so <p>hello <strong>world</strong></p> stays on one line). <pre>, <textarea>, <script>, and <style> content is preserved verbatim — formatting them would break their semantics.

Minify drops HTML comments entirely, collapses whitespace between tags, and collapses runs of whitespace inside text content to a single space. Preserved elements (script, style, pre, textarea) are left alone. The output parses identically to the source.

What CSS formatting and minification do

Format indents declarations one per line, normalises spacing around colons (color:red becomes color: red), and pretty-prints @media, @supports, @keyframes blocks with their inner rules indented further.

Minify drops /* ... */ comments, removes whitespace inside selectors (a > b becomes a>b), removes whitespace around colons and semicolons, drops the trailing semicolon in each rule, and collapses whitespace runs to nothing.

What JS minification does (and doesn’t)

Minify drops // line and /* */ block comments, then collapses whitespace using a state-machine tokeniser. The tokeniser preserves string literals, template literals (including the contents of ${...} expressions verbatim), and regex literals. The regex-vs-division heuristic uses the standard preceding-token rule (regex is allowed after =, (, [, ,, ;, {, !, &, |, ?, :, return, typeof, in, of, delete, void, instanceof, new).

What the JS minifier does NOT do:

  • AST-level transforms (no variable renaming, dead-code elimination, property mangling)
  • Tree-shaking
  • Module bundling
  • Format JS — the formatter button shows an error pointing at prettier.io

For production-grade JS minification, use terser. This tool is for quick whitespace + comment cleanup of small snippets.

Example: minifying a CSS rule for production

Source:

.button {
  background: #007bff;
  color: white;
  padding: 0.5rem 1rem;
  border: 1px solid #0056b3;
  border-radius: 4px;
}

Minified:

.button{background:#007bff;color:white;padding:0.5rem 1rem;border:1px solid #0056b3;border-radius:4px}

About 30% smaller. For a stylesheet of 1000 such rules, that’s a meaningful download saving.

Example: formatting a minified HTML email template

You inherited a minified HTML email blob from a marketing tool — one giant line, impossible to inspect. Switch to HTML, format, paste. The tool indents the table-based layout, makes nesting visible, and preserves the inline styles and image references untouched.

Example: cleaning up an unminified script for inline use

You have a small JS snippet you want to inline in a script tag. Switch to JS, minify, copy. Paste into the <script> block. About a 20-30% size reduction for typical hand-written code (the savings come from comments and indentation; production code that’s already squashed sees less).

Common mistakes

Trying to minify TypeScript with the JS mode. The JS tokeniser only handles JavaScript syntax. TypeScript’s type annotations (: string, <T>, as Foo) will confuse it. Compile to JS first.

Minifying CSS that uses @import. The minifier preserves @import lines correctly, but the imported file isn’t bundled. Production builds usually want @imports resolved before minification.

Expecting the JS minifier to rename variables. It doesn’t — only whitespace and comments. If you need shorter variable names in your output, you need terser or a similar AST-based minifier.

Pasting unbalanced HTML and being surprised by the formatter’s output. The HTML tokeniser is lenient — it’ll do its best with malformed input but the result may surprise you (e.g. a missing close tag causes the rest of the document to nest under the open tag). Validate first if your HTML might be broken.

What this tool does not do

It does not bundle modules. ES modules with import / export aren’t tree-shaken or combined.

It does not transpile. ES2022+ features pass through to the output as-is; if your target needs ES5, run Babel first.

It does not handle non-CSS preprocessors. SCSS, LESS, and Stylus syntax will confuse the CSS tokeniser. Build first, minify here.

It does not validate syntax. Garbage HTML/CSS/JS produces best-effort output; parse failures don’t always surface as errors. For pattern-based find/replace across the formatted output, the regex tester runs a rule you can verify before applying it at scale.

Frequently asked questions

Why doesn't this format JavaScript like Prettier?

Real JS pretty-printing needs an AST — parsing JS into a syntax tree and then re-emitting it. The libraries that do this well (prettier, babel, swc) are 100-700KB and run on a full ES grammar. Shipping a half-implementation produces wrong indentation on async/await, generators, JSX, decorators, and TypeScript syntax — worse than not shipping at all. For real JS formatting, paste into prettier.io. The minifier here drops comments and collapses whitespace using a state-machine tokeniser; it preserves strings, template literals, and regex literals correctly, but does not perform AST-level transforms (no mangling, dead-code elimination, or property renaming).

What's preserved when I minify HTML?

<pre>, <textarea>, <script>, and <style> blocks are preserved verbatim — their inner whitespace and content are not touched. HTML comments are dropped entirely. Whitespace between tags is collapsed to nothing; whitespace inside text content is collapsed to a single space. Doctype declarations and the structure of attributes are kept as-is. The result parses identically to the source in any browser, just with less whitespace.

Why does my CSS minified output look almost the same as my input?

If your input is already minified or close to it, there's not much to remove. Common reasons compression looks weak: input was already squashed by a build step, mostly long property values (like long base64-encoded backgrounds), or many CSS variable references. The 'saved bytes' counter shows exactly how much was removed — under 5% means the input was already lean.

Will the JS minifier break my code?

Whitespace-only minification preserves semantics for well-formed JavaScript. The state machine handles strings, template literals, and regex literals correctly. Where it can break: input with non-standard syntax (TypeScript, JSX without compilation), input that already has subtle bugs around automatic-semicolon-insertion (`return\n{a:1}` becomes `return undefined`), or input using ES2022+ features the minifier doesn't recognise. If your output behaves differently from the input, the source was probably ASI-fragile — fix by adding explicit semicolons before minifying.

Does this handle SCSS, LESS, or PostCSS?

No — only standard CSS. SCSS nesting, mixins, variables, and operators are not parsed. The CSS tokeniser will get confused by `&` selectors and `@include` directives. For preprocessor input, run the build step first (sass / lessc / postcss) and minify the resulting CSS here.