JavaScript Minifier

Minify JavaScript with Terser.

Runs locallyYour input is processed in this tab. The editor blocks outgoing network requests.
JS input

The JavaScript Minifier shrinks scripts with Terser: it removes whitespace and comments, shortens local variable names and drops code that can never run, then shows how many bytes you saved. Use it for snippets, embeds, bookmarklets and quick size checks outside a build pipeline. Everything runs in your browser — nothing is uploaded.

How to minify JavaScript

  1. Paste code, drop a .js, .mjs or .cjs file, or choose Load example.
  2. Check ES module: it is off by default, which keeps top-level functions that HTML or other scripts may call. Turn it on for module files, so unused top-level code can be dropped and top-level await is accepted.
  3. Copy with ⌥/Alt C or download with ⌘/Ctrl S. The Beautify Next action opens the result in the JavaScript Formatter.

Examples

Utility module

An exported function with the default settings. Parameters and locals are renamed; the export name stays.

JavaScript
export function debounce(fn, ms = 250) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), ms);
  };
}

Result:

JavaScript
export function debounce(e,t=250){let o;return(...u)=>{clearTimeout(o),o=setTimeout(()=>e(...u),t)}}

Dead code removal

With ES module on, top-level names are private to the file. DEBUG is a constant false, so the compressor removes the branch and the constant entirely.

JavaScript
const DEBUG = false;
export function log(msg) {
  if (DEBUG) {
    console.log("[debug]", msg);
  }
  return msg.trim();
}

Result:

JavaScript
export function log(r){return r.trim()}

Keeping a license banner

The /*! comment survives and the ordinary // comment does not. With ES module off, the default, the top-level sum function is kept by name, so other scripts can still call it.

JavaScript
/*! mylib v1.2.0 | MIT License */
// internal helper
function sum(values) {
  let total = 0;
  for (const v of values) total += v;
  return total;
}
window.sum = sum;

Result:

JavaScript
/*! mylib v1.2.0 | MIT License */
function sum(n){let o=0;for(const u of n)o+=u;return o}window.sum=sum;

Readable names with Mangle names off

The first example again with Mangle names off: whitespace is gone, but names stay readable for debugging.

JavaScript
export function debounce(fn, ms = 250) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), ms);
  };
}

Result:

JavaScript
export function debounce(fn,ms=250){let timer;return(...args)=>{clearTimeout(timer),timer=setTimeout(()=>fn(...args),ms)}}

Options explained

  • Mangle names — renames local variables and parameters to the shortest available names; exported names, globals and property names are never renamed.
  • Compress — applies Terser's code optimizations: removing unreachable branches and unused code, inlining single-use functions and joining statements with commas.
  • ES module — off by default. When on, the input is parsed as an ES module, which enables top-level await, applies strict mode, and treats top-level names as private to the file, so unused ones can be removed.
  • Keep license comments — keeps comments that begin with /*! or contain @license or @preserve; every other comment is removed.

Common JavaScript minification problems

The output is empty

With ES module on, top-level declarations are private to the file, so anything that is neither exported nor used is dead code and Terser removes it. A notice explains this when nothing is left. Add export to what other code needs, or turn ES module off to minify a classic script whose functions are called from HTML or other scripts.

"Unexpected token: operator (<)"

The input contains JSX. The minifier reads plain JavaScript only, and the error hint says so. Compile JSX with your build tool first; to tidy JSX source instead, use the JavaScript Formatter.

"TypeScript syntax at line N — the minifier accepts JavaScript only."

Interfaces, type aliases, enums and annotations such as const x: number = 1 are not JavaScript, so the input is rejected before minification starts. Remove the types — tsc or your bundler does this — and minify the emitted .js. The TypeScript Formatter can format the source, but it does not strip types.

"Unexpected token: name" after await

Top-level await is only valid in modules, and ES module is off by default. Turn it on, or wrap the code in an async function.

A global function stopped working

With ES module on, a top-level function may be renamed, inlined or removed, so code in other scripts or in onclick attributes can no longer reach it. Turn ES module off again, or assign it explicitly, as in window.sum = sum.

FAQ

Is Terser the same as UglifyJS?

Terser began as a fork of UglifyJS that added support for modern syntax, and it keeps a compatible set of options. If you are looking to uglify JS, this is the same kind of minification: whitespace removal, name mangling and compression. It understands ES2015 and later — arrow functions, classes, let/const, optional chaining and modules.

Will minified code behave the same?

It should, for code that does not depend on its own source text. Terser's transformations preserve behaviour. Two things can differ: Function.prototype.name and fn.toString() reflect the mangled names, and with ES module on, globals that other scripts expected may disappear. Test the minified file the same way you test the original.

How much smaller will my file be?

Formatted code with comments typically shrinks by 30–70%, depending on how many long local names and how much dead code it contains. The example with a DEBUG flag saved 68%. Already-minified code saves almost nothing. The figure shown is raw size; gzip or Brotli on your server reduces the transferred size further.

Can I minify TypeScript directly?

No. The minifier parses JavaScript, so type annotations, interfaces and enums must be compiled away first; TypeScript input is rejected with the line where the syntax was found. Run your TypeScript compiler or bundler, then paste the output here. To tidy TypeScript source without compiling it, use the TypeScript Formatter.

Is it safe to paste unreleased code?

Yes. Terser runs locally in your browser, inside an isolated editor frame that blocks network requests, so your code is never uploaded or stored on a server. Settings are remembered on this device; the code is saved only if you turn on "Remember my last input", and then only in this browser.

Should I use this instead of my bundler?

For application builds, keep minification in your bundler, which can also produce source maps. This page is for everything outside that pipeline: inline scripts, bookmarklets, third-party snippets and checking what Terser does with a piece of code. For stylesheets, use the CSS Minifier.

Expand minified code with the JavaScript Formatter, compress styles in the CSS Minifier, or browse all code tools.

Browse all Code Formatters