How to Minify CSS, JavaScript and HTML: Real Savings and Risks
Minifying strips comments and whitespace so files download faster. Measured savings on real files, minify vs gzip and brotli, source maps, and when it breaks code.
To minify CSS, JavaScript or HTML, run it through a minifier that deletes comments, indentation and line breaks the browser doesn't need. For a quick job, paste the code into the free CSS minifier, JavaScript minifier or HTML minifier and copy the result. For a website you maintain, use a build tool such as esbuild, terser or cssnano, which understand the code and save far more on JavaScript.
We measured both on real files. On Bootstrap 5.3.3, minifying cut the stylesheet by about 17% and the JavaScript by 28% to 58%, depending on the tool. This guide shows those numbers, how minifying adds to gzip and brotli compression, and the cases where a simple minifier breaks working code.
What minification removes
A basic minifier removes only what the browser ignores: comments, indentation, blank lines and spaces around punctuation. The site's CSS minifier turned these 117 characters into 83, about 29% smaller:
/* Buttons */
.btn {
padding: 10px 20px;
background: #6d48f5;
}
.btn:hover,
.btn:focus {
background: #5b3ae0;
}
.btn{padding:10px 20px;background:#6d48f5}.btn:hover,.btn:focus{background:#5b3ae0}
A full minifier goes further. For CSS it shortens colours and zeros, and merges duplicate rules. For JavaScript it renames local variables to single letters, drops unreachable code and rewrites statements into shorter equivalents. That renaming is why proper JavaScript minifiers save so much more than whitespace removal.
How much it saves: measured on real files
We ran Bootstrap 5.3.3's unminified bootstrap.css and bootstrap.js, and the 61 KB HTML of one of our own blog pages, through the site's minifiers and through standard build tools (October 2026). Sizes are in kilobytes; percentages are the reduction from the original.
| File | Original | Site's minifier | Build tool |
|---|---|---|---|
| bootstrap.css | 274.5 KB | 229.4 KB (16%) | 226.5 KB, cssnano (18%) |
| bootstrap.js | 142.0 KB | 102.3 KB (28%) | 59.1 KB, terser (58%) |
| Blog page HTML | 61.1 KB | 55.6 KB (9%) | 56.2 KB, html-minifier-terser (8%) |
esbuild landed next to the others: 227.6 KB for the CSS and 59.9 KB for the JavaScript. Bootstrap's own shipped files, bootstrap.min.css and bootstrap.min.js, are 227.3 KB and 59.2 KB. So for CSS and HTML, whitespace removal gets you nearly all of the benefit. For JavaScript, the site's light minifier gets about half of what a real one does.
Minify vs gzip and brotli
Most web servers also compress text files on the way out, with gzip or the newer brotli. Compression and minification overlap: gzip is very good at squeezing repeated whitespace. The real question is what visitors download after both. We compressed each file with Node.js at maximum settings (gzip level 9, brotli quality 11):
| File | Original + gzip | Site's minifier + gzip | Build tool + gzip |
|---|---|---|---|
| bootstrap.css | 32.2 KB | 29.8 KB | 30.1 KB |
| bootstrap.js | 28.6 KB | 22.5 KB | 16.1 KB |
| Blog page HTML | 13.2 KB | 12.7 KB | 12.8 KB |
With brotli instead of gzip, the build-tool versions came to 22.4 KB, 14.4 KB and 10.7 KB, against 23.9 KB, 23.6 KB and 11.1 KB for the unminified files.
Three conclusions follow:
- Compression matters most. The 274.5 KB stylesheet travels as 32.2 KB with gzip alone. If your server isn't compressing, fix that first. In Chrome DevTools, open the Network tab, click a CSS or JS file and look for
content-encoding: gziporbrin the response headers. - Minifying CSS and HTML still helps, a little. After gzip it saved about 2.4 KB on the stylesheet and 0.5 KB on the page. It also means less text for the browser to parse.
- Minifying JavaScript with a real tool helps a lot. terser cut the gzipped script from 28.6 KB to 16.1 KB, a 44% saving that compression alone can't reach, because renaming variables removes information gzip has to keep.
Servers usually compress at lower settings than we used, for speed, so real transfer sizes will be slightly larger. The proportions hold.
Is the site's minifier a parser? No, and here is what that means
All three of the site's minifiers work with text patterns (regular expressions), not by parsing the code. That makes them fast and predictable, but they can't tell a comment from a string that looks like one. Here is exactly what each does, and what broke in our tests.
CSS minifier
It removes every /* … */ comment, deletes spaces around { } : ; , >, drops the last semicolon in each block and collapses other whitespace to one space. Two side effects:
- A space before a colon in a selector is meaningful.
.was-validated :valid ~ .valid-feedback(any valid field inside the form) became.was-validated:valid ~ .valid-feedback(the form itself is valid). That rule is in Bootstrap, along with its:invalidtwin, so the minified file would stop showing the green and red feedback messages under form fields. - Strings are not protected.
content: "Note ; read this"becamecontent:"Note;read this".
It also deletes /*! … */ licence banners, which cssnano keeps by default. If you ship third-party CSS, put the licence line back.
JavaScript minifier
It removes /* … */ blocks, deletes lines that start with //, strips indentation and blank lines. It keeps every line break, which makes it safe for code that leaves out semicolons, and it doesn't rename anything. Bootstrap's script still parsed after it. The risks come from strings:
const files = "src/**/*.js";becameconst files = "src*.js";, because/**/inside the string looked like a comment.- Inside a multi-line template literal, a line starting with
//was deleted, changing the text.
Comments at the end of a line, like let total = 0; // running total, are left in. Use it for small scripts you can test, not for a production bundle.
HTML minifier
It removes all comments and every bit of whitespace between a > and the next <, then turns any run of two or more whitespace characters into one space. On this input:
<p>Price: <strong>₹499</strong> <em>only</em></p>
the space between the two inline elements disappeared, so the page would read "₹499only". Text in <pre> lost its line breaks and indentation. Worst, in an inline script, the line break and indentation after // set theme became a single space, so the following lines became part of the comment and never ran. html-minifier-terser, which parses the page, kept the space, left the <pre> alone and minified the script correctly.
If you use the online minifiers, keep these rules: no // comments inside inline scripts, no reliance on spaces between inline tags, and test the page afterwards.
Source maps: debugging minified code
Minified JavaScript is unreadable in the browser's error messages: everything is on line 1 and the names are single letters. A source map is a separate .map file that links each part of the minified file back to your original source. Browser DevTools load it automatically and show your real file names, lines and variable names.
When we ran npx esbuild app.js --minify --sourcemap --outfile=app.min.js, esbuild wrote app.min.js.map and added this last line to the minified file:
//# sourceMappingURL=app.min.js.map
That comment is how DevTools finds the map. The map only downloads when DevTools is open, so it doesn't slow down normal visitors, but anyone can read it, which exposes your original source. Many teams upload maps to their error-tracking service instead of the public server. The site's online minifiers don't make source maps.
Build tools that minify for you
If you run Node.js, these commands, all tested with the current versions in October 2026, minify as part of your build:
- esbuild (JavaScript and CSS):
npx esbuild app.js --minify --sourcemap --outfile=app.min.js. The same command withstyle.cssminifies a stylesheet. - terser (JavaScript):
npx terser app.js --compress --mangle -o app.min.js.--manglerenames variables;--compressrewrites code. - cssnano (CSS, runs inside PostCSS):
npx postcss style.css -u cssnano --no-map -o style.min.css, with postcss, postcss-cli and cssnano installed. Without--no-map, postcss-cli embedded a source map in the output and our minified stylesheet came out at 711 KB, bigger than the original. - html-minifier-terser (HTML):
npx html-minifier-terser --collapse-whitespace --conservative-collapse --remove-comments --minify-css true --minify-js true -o page.min.html page.html.
Frameworks such as Vite, Next.js and Laravel's Vite setup minify automatically in production builds. On WordPress, caching and performance plugins usually have a minify option; switch on one file type at a time and check the site after each.
A safe minify workflow
- Keep your readable source files and edit only those. Never edit the
.minfile. - Minify as the last step, ideally automatically in your build.
- Make sure the server sends gzip or brotli.
- Test the minified version: forms, menus, anything with JavaScript.
- Change the file name or add a version (
style.min.css?v=2) so browsers fetch the new file instead of a cached copy.
To read a minified file again, the CSS beautifier and HTML formatter lay it out with indentation; our guide on how to beautify CSS, HTML and XML explains their limits. For JSON data, the JSON minifier parses the data first, so it can't break strings.
Frequently asked questions
Does minifying change how my code works?
It shouldn't, and parser-based tools like terser, esbuild and cssnano are built not to. Pattern-based minifiers, including the ones on this site, can change strings, CSS selectors with a space before a colon, and inline scripts with // comments. Always test the minified version.
Should I minify if my server already uses gzip?
For JavaScript, yes: a real minifier cut our gzipped test file by 44%. For CSS and HTML the gain after gzip was 3–8%, still worth having if your build does it automatically, but not worth risking a broken page by hand.
Is minified code harder to steal?
Barely. Anyone can reformat it, and only the variable names and comments are lost. Minify for speed, not secrecy.
Can I un-minify a file?
You can restore the layout with a beautifier or VS Code's Format Document, but not deleted comments or original variable names. If the site published a source map, DevTools can show the original code.
Is my code uploaded when I use the online minifiers?
No. The CSS, JavaScript and HTML minifiers run in your browser. The Input box shows a character count; the tool doesn't report the saving, but you can paste the result back into the box to see its new count.
What is the difference between minify and compress?
Minifying rewrites the file itself into a smaller but still valid file. Compression (gzip, brotli) packs the bytes for transfer, and the browser unpacks them. Use both.
Sources: Measurements on Bootstrap 5.3.3 and an EthicalFusion page with the site's minifiers, esbuild 0.28, terser 5.51, cssnano 8.0 and html-minifier-terser 7.2, Node.js 24 zlib, October 2026.
- #minify css
- #minify javascript
- #minify html
- #gzip vs minify
- #source maps
- #esbuild terser cssnano