JavaScript Minifier



How to Use the JavaScript Minifier

1

Paste your JavaScript code

Paste your JavaScript code.

2

Click Minify

Click Minify.

3

Copy or download the minified JS

Copy or download the minified JS.

JavaScript Minifier — Reduce JS Bundle Size for Faster Page Performance

JavaScript is the most expensive resource a web page loads. Images can be deferred and lazy-loaded. CSS, once downloaded, is parsed quickly into a stylesheet object. But JavaScript blocks the browser's main thread during download, parsing, and execution — every millisecond the browser spends processing your script is a millisecond the page sits unresponsive to user interaction. Minifying your JavaScript removes the characters that add to that cost without adding functionality: comments, whitespace, optional semicolons, and (in advanced mode) verbose local variable names. The result is a smaller file that transfers faster, parses faster, and starts executing sooner.

Paste any JavaScript into this tool — your own code, a utility script, or a library you need compressed — and get minified output in seconds. The entire process runs in your browser. Copy the result or download it as a .min.js file ready for production.

What Minification Removes — and the Order of Operations

JavaScript minification is not a simple text replacement. A proper minifier parses the code into an Abstract Syntax Tree (AST) to understand its structure before making any changes. This matters because JavaScript has context-sensitive grammar — a semicolon, a newline, or a string that looks like a comment might be significant or insignificant depending on where it appears. Working from the AST eliminates ambiguity.

Stage 1 — Whitespace and comment removal: All whitespace between tokens that is not required by the grammar is removed. All single-line (//) and block (/* */) comments are removed. This alone typically reduces file size by 20 to 35 percent.

Stage 2 — Variable and function name mangling: Advanced minifiers like Terser perform scope analysis to identify local variable names that are only referenced within their declaring function or block. These can be safely renamed to single characters (longDescriptiveName becomes a) across the entire scope without changing behavior. This step adds another 15 to 30 percent reduction. Names that are exported, globally accessible, or referenced from external code are never mangled.

What is never removed: String values, regular expression patterns, function logic, exported names, global variable references, and any character whose removal would change the program's observable behavior. Minifiers are conservative — when in doubt, they keep the code.

AST-Based Minification — Why Parsing Matters

The distinction between text-based compression and AST-based minification is fundamental. A naive text-based approach might replace multi-space indentation with single spaces, strip comments using regex, or collapse newlines. This works for simple cases but breaks in others. Consider a multi-line string: const msg = "Hello\nWorld". A regex that blindly strips newlines would corrupt the string content, turning the escaped newline into a literal line break in the output. An AST-aware minifier knows that \n inside a string literal is part of the string's value and leaves it untouched.

Modern minifiers like Terser, UglifyJS, and esbuild all operate on ASTs. The process goes: tokenize the source into tokens, parse tokens into a tree structure that represents the program's logic, transform the tree (removing dead branches, shortening names, simplifying expressions), and finally generate new source code from the transformed tree. This pipeline ensures that every transformation preserves the program's semantic behavior.

AST-based minification also enables expression simplification. The minifier can convert if (x === true) into if (x), or var x = a ? true : false into var x = !!a, or collapse constant expressions like const x = 3 * 4 into const x = 12 at compile time. These micro-optimizations add up across a large codebase and are impossible with simple text replacement.

Mangling vs. Minifying — They Are Not the Same

Minification and mangling are often conflated, but they serve different purposes within the minification pipeline. Minification is the broad term for all size-reducing transformations: removing whitespace, stripping comments, simplifying expressions, and shortening literals. Mangling specifically refers to renaming identifiers — shortening variable names, function names, and parameter names to shorter (usually single-character) alternatives.

You can minify without mangling. Many developers do this during development or when debugging minified output: strip comments and whitespace, but keep variable names intact. This gives you roughly 20 to 35 percent reduction without making the code harder to read. Terser supports this with the -c (compress) flag without -m (mangle).

Mangling adds another 10 to 30 percent on top of minification, but the output is significantly harder for humans to read. Variable names become a, b, c, function parameters become t, n, e. This is fine for production code that ships to users, but it makes debugging nearly impossible without source maps. The decision of whether to mangle often depends on context: mangling your own application code is standard practice, but mangling library code during development is usually counterproductive.

Terser offers fine-grained control over mangling. You can mangle property names (shortening object keys), exclude specific names from mangling (useful when you need element.id to survive), or mangle only top-level names. The mangle.properties option is powerful but dangerous — it will rename all property accesses, breaking any code that relies on string-based property access like obj["dynamic_" + key].

Dead Code Elimination

Dead code elimination removes code that can be proven unreachable at runtime. The minifier identifies branches, functions, and variable declarations that are never referenced, or conditionals that always evaluate to the same value, and strips them from the output.

The most common case is removing code inside if (false) blocks. Development-only logging, debug utilities wrapped in environment checks, and feature flags set to fixed values all fall into this category. A minifier with dead code elimination will remove:

// Before minification
if (process.env.NODE_ENV !== 'production') {
    console.log('Debug:', userData);
    performance.mark('operation-start');
}

// After minification (dead code removed)

Dead code elimination also removes unused function declarations and variable bindings that are never read. If you define a helper function but never call it, or import a utility but never use it, the minifier can remove it entirely. This is related to — but distinct from — tree shaking, which operates at the module level during bundling rather than within a single file.

One limitation: dead code elimination cannot remove code that has side effects. Calling fetch(), modifying the DOM, writing to localStorage, or mutating global state all have observable effects that the minifier must preserve. Even inside a dead-code-looking block, if the code calls a function that might have side effects, the minifier has to keep it.

Tree Shaking: Eliminating Dead Code Before Minifying

Tree shaking is a separate optimization that works alongside minification but at a higher level. While minification compresses existing code, tree shaking eliminates code that was imported but never actually used — dead code at the module level. If you import a utility library with 200 functions but only use 3 of them, tree shaking removes the other 197 from your bundle entirely.

Tree shaking relies on ES module syntax (import/export) and static analysis. Bundlers like Webpack, Rollup, and Vite analyze the import graph at build time, identify unused exports, and exclude them from the output. CommonJS modules (require()) generally cannot be tree-shaken because their dynamic nature makes static analysis unreliable.

The combined effect of tree shaking plus minification is substantial. A project that imports a large library but uses a fraction of it might see 60 to 80 percent of that library removed by tree shaking, then the remaining code compressed another 40 to 60 percent by minification. The two optimizations are complementary — tree shaking runs during bundling, minification runs after.

For tree shaking to work effectively, libraries must be published as ES modules with proper export declarations. If a library re-exports everything through a single barrel file without side-effect-free markers (/*#__PURE__*/ comments), the bundler may conservatively include the entire module. Checking a library's package.json for a "sideEffects": false flag helps determine whether it's tree-shakeable.

Source Maps: Debugging Minified Code Without Losing Your Mind

The trade-off of minified JavaScript is that it is effectively unreadable for debugging. Variable names are single characters, everything is on one or a few lines, and error stack traces point to positions like 1:32847 instead of meaningful line numbers. Source maps solve this entirely.

A source map is a separate .js.map file that maps every position in the minified output back to the corresponding position in your original source file. When you load a page with source maps and open browser DevTools, the debugger uses the map to show you the original code with original variable names, comments, and line numbers — even though the browser is executing the minified version. You can set breakpoints in the original source, step through code, and read error messages referencing real file names.

Modern build tools generate source maps automatically. For production deployments where you do not want source maps publicly accessible, you can generate them and restrict access via server configuration — they still work in DevTools for your team but are not downloaded by regular users. A common pattern is serving source maps behind authentication or only generating them in staging builds.

Source maps also integrate with error monitoring services. Tools like Sentry and Datadog can use source maps to de-minify stack traces from production errors, turning unreadable minified traces back into the original file names and line numbers. This means you get the performance benefit of minified code in production without losing the ability to debug real errors.

Minification in Bundlers — Webpack, Rollup, Vite, and esbuild

In modern development workflows, minification rarely happens as a standalone step. Instead, it's configured as part of a bundler's production build pipeline, where it happens automatically alongside tree shaking, code splitting, and module concatenation.

Webpack: Uses Terser via the terser-webpack-plugin (included by default in production mode). Webpack's configuration lets you define separate minification settings for JavaScript and CSS, split chunks that get independently minified, and configure source map generation per-chunk. The standard Webpack 5 production config enables minification, tree shaking, and scope hoisting together.

Rollup: Supports Terser as a plugin (@rollup/plugin-terser). Rollup is particularly popular for library development because its output is clean and its module-level tree shaking is considered the best in the ecosystem. Library authors using Rollup can configure minification to preserve specific names (like library exports) while mangling internal variables.

Vite: Uses esbuild for development builds (extremely fast) and Rollup for production builds. Esbuild is written in Go and minifies JavaScript 10 to 100 times faster than JavaScript-based minifiers. In development, this speed difference means near-instant rebuilds. For production, Vite delegates to Rollup with Terser for more thorough optimization.

esbuild: A standalone bundler/minifier written in Go. Esbuild's minification is blazing fast but historically less thorough than Terser — it does not perform as many expression simplifications or as aggressive mangling. For many projects, this trade-off is acceptable. Esbuild does support source maps, tree shaking, and CSS minification.

Terser Options — Fine-Tuning Your Minification

Terser is the most widely used JavaScript minifier in the ecosystem. Understanding its configuration options lets you balance size reduction against safety for your specific codebase.

Compress options (-c): Controls which transformations are applied. Key options include drop_console (removes all console.* calls), drop_debugger (removes debugger statements), pure_funcs (marks specific functions as side-effect-free so their calls can be removed), and passes (number of compression passes — more passes catch more optimization opportunities but take longer).

Mangle options (-m): Controls identifier renaming. The mangle.properties option can shorten object property names globally, which saves significant space but breaks any code using dynamic property access. The reserved option prevents specific names from being mangled — useful when you need to preserve names for API contracts or third-party integration.

Output options: Control formatting of the minified output. comments lets you preserve specific comments (like license headers) using a regex or function. wrap_iife wraps immediately-invoked function expressions in parentheses. ascii_only escapes non-ASCII characters to ensure the output is safe for all environments.

A practical Terser configuration for production might look like: compress with drop_console: true, drop_debugger: true, pure_funcs: ['console.log', 'console.info'], and passes: 2. Mangle with default settings (no property mangling). Output with a license comment preserved. This configuration safely removes debugging artifacts, simplifies expressions, and produces the smallest output without risky transformations.

Minification vs. Obfuscation — Different Goals

Minification and obfuscation are frequently confused, but they serve fundamentally different purposes. Minification optimizes for performance: the output is smaller and faster to transfer and parse, but the code remains structurally readable after formatting. Obfuscation optimizes for protection: the output is deliberately made harder for humans to understand, with renamed variables, control flow flattening, dead code injection, and string encoding.

A minified file can be formatted back into readable code in seconds using any code formatter. An obfuscated file requires significant reverse-engineering effort. However, even obfuscation is not true security — the code must ultimately execute in the browser, which means it can be analyzed by anyone with sufficient motivation and tools.

For most web applications, minification is the right choice. It gives you the performance benefit without the debugging complexity obfuscation introduces. Obfuscation makes sense for commercial JavaScript products where you want to raise the barrier to casual copying, but it should never be relied upon as a security mechanism.

CSS and HTML Minification — The Full Picture

While this tool focuses on JavaScript, a complete performance optimization strategy also minifies CSS and HTML. CSS minification removes comments, whitespace, and shortens color values (#ffffff becomes #fff) and selectors where safe. HTML minification strips comments, optional tags, and collapses whitespace. Tools like html-minifier-terser, cssnano, and build-tool plugins handle these automatically.

Combining minification across all three file types (JS, CSS, HTML) with Gzip or Brotli transfer compression on your server gives you the full performance stack. A 500KB JavaScript file minified to 150KB and then Brotli-compressed to 40KB reaches the browser in roughly one-twelfth the time of the original — a dramatic difference on mobile networks.

Frequently Asked Questions About JavaScript Minification

A correctly written minifier will not break valid JavaScript. The edge cases that can cause issues are rare in modern code: eval() with strings referencing mangled variable names, Function.prototype.name reads after renaming, and code relying on arguments.callee in strict mode. For standard ES5+ code, minification is safe. Always test your minified output before deploying to production.
Whitespace and comment removal alone reduce files by 20 to 40 percent. Variable mangling adds another 10 to 30 percent on top. A well-commented, verbosely named file can easily see 60 to 70 percent total reduction. Combined with Gzip or Brotli transfer compression, the over-the-wire size is typically 80 to 90 percent smaller than the original uncompressed source.
Minification does not change what the code does at runtime, so it does not speed up the logic itself. What it improves is parse time — browsers have fewer tokens to process during parsing and compilation. For large bundles on mobile devices, this parse-time improvement is measurable. Minification also improves download time, meaning code starts executing sooner. Both contribute to faster Time to Interactive (TTI).
Use a bundler that handles minification as part of the production build. Vite uses esbuild by default, Webpack uses Terser Plugin, Rollup supports Terser as a plugin. For plain JavaScript without a bundler, run Terser from the command line: npx terser input.js -o output.min.js -c -m. For one-off tasks, this online tool is the fastest option — no setup required.
Minification makes code harder to casually read but provides no real protection. Anyone can run your minified code through a formatter and get readable code back. Variable names are shortened, making logic harder to follow, but determined reverse engineering will succeed. True code protection requires intentional obfuscation — and even that is not foolproof since the code must ultimately be executable in the browser.
Most popular libraries already ship minified versions in their npm packages — the .min.js file in jQuery or the production build of React. Re-minifying these is pointless. Where minification matters is your own application code and any in-house libraries. Your build tool handles this automatically when you have a production build step configured.
Minification is a permanent transformation of the source code — comments and whitespace are removed, names are shortened, and the resulting file is smaller on disk. Compression (Gzip, Brotli) is a transfer-level optimization — the server compresses the file before sending it, and the browser decompresses it on receipt. Both reduce over-the-wire size, but they work at different layers and are complementary. Always use both for production.
Esbuild is written in Go and runs parallelized compilation passes across all available CPU cores. Terser is written in JavaScript and runs single-threaded in a single process. The raw computational speed difference is 10 to 100x. Esbuild also performs fewer optimization passes, which contributes to both its speed and slightly less aggressive output. For most applications, esbuild's speed and output quality are a strong combination.