Minify JS & CSS

Paste code and the minified version appears as you type — with the characters saved.

How to use it

  1. Paste JavaScript or CSS into the box — the minified version appears as you type, there is no button to press.
  2. Leave the syntax on Auto, or pick JavaScript / CSS yourself if the detection guessed wrong; the result re-renders immediately.
  3. The header shows the characters saved before → after. Copy the output or download it as a .js / .css file.

Example

Input

// Cart total with the free-shipping badge
const TAX = 0.08;

function total(items, coupon) {
  let sum = 0;
  for (const item of items) {
    sum += item.price * item.qty;
  }
  if (coupon) {
    sum -= coupon;
  }
  return { amount: sum * (1 + TAX), freeShipping: sum > 50 };
}

Minified

const TAX=0.08;function total(items,coupon){let sum=0;for(const item of items){sum+=item.price*item.qty;}if(coupon){sum-=coupon;}return{amount:sum*(1+TAX),freeShipping:sum>50};}

The comment is gone and the whitespace is collapsed, but every identifier keeps its name and every literal keeps its exact spelling. The reading says 279 → 177 characters (−37%).

Rules, limits and known issues

  • Whitespace and comments only. Nothing is renamed, no statement is folded and no code is removed — so minified output behaves like the original, but is larger than what Terser produces.
  • Comments starting with /*! or //!, and comments mentioning @license or @preserve, are kept; every other comment is removed.
  • Line breaks stay wherever removing them would change the program: after return / throw / break / continue / yield / async, and between two statements where JavaScript would insert a semicolon automatically (a\nb, x={}\nfoo()). Most other code comes out as one line.
  • JavaScript is tokenised, not parsed: "/*" inside a string, a regular expression or a template literal is never touched. Division and regular expressions are told apart by the previous token; a regex that spans a line is treated as division.
  • CSS only loses whitespace that cannot mean anything: around { } ; , > ~ ! and after ":", and the last ";" before a "}". Descendant spaces stay (.a .b is not .a.b), the space before ":" stays (a :hover is not a:hover), and calc(100% - 10px) keeps its spaces because they are part of the syntax.
  • No renaming (mangle), no dead-code removal, no drop_console: those change behaviour, which is not something a "minify" button should do silently.
  • Not supported: HTML/SVG (whitespace there depends on <pre>, <textarea> and inline elements), TypeScript type-level rewrites, JSX/TSX input, source maps and multi-file merging. JSX is detected and flagged with a warning.
  • An unclosed string, template, comment or url( at the end of the input is a warning, not an error: the rest of the code is still minified. Unbalanced brackets are a warning too — this is not a validator.
  • Readings count Unicode code points, not bytes and not UTF-16 units; percentages are rounded to a whole number and shown as +n% when the output grows. Everything runs in your browser: nothing is uploaded, stored or added to the URL.
  • Above 200,000 characters the result updates about 0.6 s after you stop typing; the text is never truncated. Output uses LF and has no trailing newline.

What people usually need next, once the code is small.