JavaScript & CSS Minifier
Paste JavaScript or CSS, then minify it with a single click. Compare UTF-8 byte sizes and copy or download the output. Your source stays in the browser.
Your code stays in this browser · 1 MB input limit
139 input bytes
Minified output
Minified code will appear here.
How this code minifier works
The JavaScript tab uses Terser to parse and compress your code. Shorten local names also lets Terser rename local identifiers. Select ES module for code that uses import, export or top-level await.
The CSS tab uses clean-css. Its default level removes unnecessary syntax and shortens values. The optional second level can combine rules for further savings. Imports are not fetched and relative URLs are not changed. Both tabs keep comments that start with /*!, the usual marker for license headers; the JavaScript tab also keeps comments that contain @license or @preserve. Always run your own tests before replacing production code, especially when enabling more aggressive options.
The byte comparison measures the original and minified UTF-8 source. It does not include gzip or Brotli transfer compression. Read the code minification guide for the differences between minifying, bundling and compressing.
What Terser changes in JavaScript
Minification is more than deleting whitespace. Terser rewrites code into shorter equivalent code. Each output below was produced by this tool from the input next to it:
| Change | Input | Output |
|---|---|---|
| Removes comments and whitespace, shortens local names and inlines a single-use variable | /* Add tax */ function total(price, taxRate) { const tax = price * taxRate; return price + tax; } | function total(t,n){return t+t*n} |
| Computes constant expressions | const secondsPerDay = 60 * 60 * 24; console.log(secondsPerDay); | const secondsPerDay=86400;console.log(86400); |
| Drops unreachable code and unused local variables | function area(r) { const unused = r * 2; if (false) { console.debug(r); } return Math.PI * r * r; } | function area(a){return Math.PI*a*a} |
| Turns if/else returns into a ternary | function sign(n) { if (n >= 0) { return "positive"; } else { return "negative"; } } | function sign(i){return i>=0?"positive":"negative"} |
| Shortens undefined, true and bracket property access | function reset(state) { state["value"] = undefined; state.done = true; } | function reset(e){e.value=void 0,e.done=!0} |
| Removes debugger statements but keeps console calls | function save() { debugger; console.log("saved"); } | function save(){console.log("saved")} |
| ES module off: top-level names are kept | function helper(x) { return x * 2; } export function double(n) { return helper(n); } | function helper(e){return 2*e}export function double(e){return helper(e)} |
| ES module on: unexported top-level code can be inlined or removed | function helper(x) { return x * 2; } export function double(n) { return helper(n); } | export function double(e){return 2*e} |
Top-level names such as total and secondsPerDay keep their names in script mode because other scripts on the page may use them. Only local names are shortened, so a minified script stays compatible with the code around it.
clean-css level 1 vs level 2
Level 1 optimizes each declaration on its own: colors, units, zeros and keywords. Level 2, enabled by Combine CSS rules, also merges longhand properties into shorthands, removes overridden declarations and merges rules that share a selector or a body:
| Input | Level 1 | Level 2 |
|---|---|---|
.card { color: #ffffff; font-weight: bold; transition: opacity 0.30s; } | .card{color:#fff;font-weight:700;transition:opacity .3s} | .card{color:#fff;font-weight:700;transition:opacity .3s} |
.box { margin: 0px 0px 16px 0px; } | .box{margin:0 0 16px 0} | .box{margin:0 0 16px} |
.box { margin-top: 8px; margin-right: 16px; margin-bottom: 8px; margin-left: 16px; } | .box{margin-top:8px;margin-right:16px;margin-bottom:8px;margin-left:16px} | .box{margin:8px 16px} |
.btn { color: red; padding: 4px; color: blue; } | .btn{color:red;padding:4px;color:#00f} | .btn{padding:4px;color:#00f} |
.a { color: red; } .b { color: red; } | .a{color:red}.b{color:red} | .a,.b{color:red} |
.a { color: red; } .a { margin: 0; } | .a{color:red}.a{margin:0} | .a{color:red;margin:0} |
Level 2 moves declarations between rules, so the result depends on the whole stylesheet. Compare the rendered page before shipping it.
JavaScript minifier error messages
Terser has to parse the code before it can compress it, so any syntax error stops minification. These are the messages this tool shows for common mistakes, with the position Terser reports:
TypeScript type annotations
let port: number = 3000;
Unexpected token: punc (:) (line 1, column 9)
Terser does not understand TypeScript. The same annotation on a const reports Missing initializer in const declaration, which points at the wrong problem. Compile with tsc or esbuild first and minify the JavaScript it emits. This tool stops early on type and interface declarations, which make Terser 5.51 run until it fails with Invalid array length.
JSX
const el = <div>Hello</div>;
Unexpected token: operator (<) (line 1, column 12)
JSX has to be compiled to function calls by Babel, esbuild or your framework's build before it can be minified.
Top-level await without ES module
const res = await fetch("/api");Unexpected token: name (fetch) (line 1, column 19)
await outside a function is only valid in modules. Enable ES module and minify again.
Missing closing parenthesis
console.log("hi";Unexpected token punc «;», expected punc «,» (line 1, column 17)
Terser reached the semicolon while still reading the argument list. Add the ) before it.
Missing closing brace
function f() {
return 1;
Unexpected token: eof (undefined) (line 3, column 1)
eof means the input ended while a block was still open. Count the { and } pairs, usually in the last function you edited.
Unterminated string
const s = "hello;
Unterminated string constant (line 1, column 11)
Close the quote. A string that needs to span lines has to be a template literal (backticks) or use \n.
Redeclared variable
const a = 1; const a = 2;
"a" is redeclared (line 2, column 7)
let and const cannot declare the same name twice in one scope. This often happens when two scripts are pasted together; rename one of the variables or wrap each script in its own block.
Return outside a function
return 1;
'return' outside of function (line 1, column 1)
The pasted code is probably the body of a function. Paste the whole function.
CSS minifier warnings
clean-css does not stop on invalid CSS. It skips what it cannot parse, returns a warning and keeps going, so check the warnings before using the output. In the second case below the whole .b rule is lost:
| Input | Warning | Output |
|---|---|---|
a{color:red | Missing '}' at 1:11. | a{color:red} |
.a { color: red;
.b { color: blue } | Invalid property name '.b { color' at 2:0. Ignoring. | .a{color:red} |
.a { color: red }} | Unexpected '}' at 1:17. Invalid character(s) '}' at 1:17. Ignoring. | .a{color:red} |
.a { color: ; } | Empty property 'color' at 1:5. Ignoring. | (empty) |
clean-css is not a validator. A misspelled property such as colr: red is kept as written, and a missing semicolon in color: red followed by margin: 0; on the next line becomes color:red margin: 0 with no warning.
Learn more
What Is Code Minification and Why It Matters for Web Performance
Minification removes whitespace, comments, and redundant code to reduce file size. Learn how CSS and JavaScript minification work, how much size they save, and what tools to use.
Why You Should Never Paste Sensitive Data Into Online Tools
API keys, JWT tokens, database URLs, passwords — pasting them into server-side tools is a real security risk. Learn what happens to your data and what client-side alternatives to use.
Related Tools
Frequently Asked Questions
Does this minifier upload my code?▾
No. The input is processed by Terser or clean-css inside a browser worker. The libraries are served as static files from this site, and your code is not sent to a server or saved in browser storage.
What is the difference between minification and gzip or Brotli?▾
Minification rewrites source code to use fewer bytes, such as removing comments and unnecessary whitespace. Gzip and Brotli encode the resulting file for transfer over the network. The size shown here is the UTF-8 source size before HTTP compression.
What does 'Shorten local names' do to JavaScript?▾
It enables Terser's identifier mangling, which shortens local variable and function names. Property names are not mangled by this option. Disable it if your code relies on specific function names or uses dynamic name lookup.
Does this tool bundle imports or transpile JavaScript?▾
No. It minifies the code you paste as one input. The ES module option tells Terser to treat that input as a module, but it does not resolve imports, combine files or transform modern syntax for older browsers.
Can I minify TypeScript or JSX?▾
No. Terser parses JavaScript only, so a type annotation or JSX tag stops with a syntax error such as Unexpected token: punc (:). Compile the file to JavaScript with tsc, esbuild or your bundler first, then minify the output.
Will CSS @import rules or relative URLs be fetched?▾
No. This tool disables clean-css import inlining and URL rebasing. It only processes the CSS text in the editor, so external stylesheets are not fetched and relative asset paths stay as written.