Free online JavaScript minifier
Minify JavaScript without renaming a thing
This strips comments and whitespace from JavaScript and stops there — free, no signup, nothing uploaded — then weighs the result four ways, including how much of the saving is still there once the file has been compressed. It does not rename identifiers and it does not tree-shake, so the saving is smaller than a build tool’s and the output is still a file you can read and diff. A 2,953-byte commented module loses 30%; esbuild takes the same file 44% down, and that gap is the renaming.
- 100% free
- No signup
- Up to 5 MB
- No name mangling
- Real gzip size
Identifiers are never renamed.
The stripped-down version appears here.
Paste a script, drop a file, or press Ctrl+V anywhere on this page.
What this deliberately does not do
- rename identifiers — cartTotal stays cartTotal, never becomes a
- remove code that is never called, or inline a function into its caller
- rewrite syntax, so true never becomes !0 and if/else never becomes a ternary
- resolve imports or bundle files together
Those four are where the other half of the saving lives, and all four need a real parser and a scope analysis. Reach for esbuild or Terser when you need them; use this when you want to be certain the file still behaves. Going the other way is the JavaScript formatter.
How to minify JavaScript
Paste it, keep the banner, read the four numbers.
Load the script
Paste the script, use ⌘V or Ctrl+V with the page focused and no box selected, or open a .js, .mjs or .cjs file. Sample module loads a small commented file if you want to see the counters move before trusting them with yours.
Decide about licence banners
“Keep /*! licence banners” is on, because MIT and Apache-2.0 both require the notice to travel with the code and a /*! comment is the convention every minifier honours for exactly that reason. Turn it off only for a file you wrote and own outright.
Take the numbers with the file
Four cells weigh the file: what it was, what it became, what came off in bytes and percent, and the same pair after compression. Copy hands over the minified text; Download writes it out under a .min.js name. Above them, a line saying how many comments went and how many tokens stayed exactly as they were.
Technical specifications
| What is removed | Comments, and every space, tab and newline that the parser does not need. That is the whole list |
|---|---|
| What is never touched | Identifiers, property and method names, string contents, numeric literals, regex patterns and flags, template literal contents, JSX regions, and the order of every statement |
| Safety rules | Line breaks that terminate a bare return, throw, break, continue or yield are kept, so automatic semicolon insertion still fires where it did; any two tokens that would weld into a different operator keep the space between them, so - -a never turns into --a |
| Measured saving | 2,953-byte commented module → 2,059 bytes, 30% off raw and 26% off gzipped; the same file with comments already gone → 20% off. Bytes before, after, saved and gzipped are reported per run |
| Compared with a real minifier | esbuild took that same 2,953-byte module to 1,664 bytes (44%) because it renames and rewrites. On already-minified input the gap closes: re-minifying eight chunks of a shipped Next.js build landed within 0.65% of what Terser had produced |
| Not done, by design | No identifier renaming, no tree-shaking or dead-code removal, no syntax rewriting (true stays true, if/else stays if/else), no constant folding, no bundling, no source map |
| When it refuses | A quote, backtick or /* that is never closed, or a bracket left open at the end of the file: your text comes back exactly as it arrived, with the reason named — a minifier that cannot read a file has no business rewriting it |
| Limits and measurement | 5 MB per file, one file at a time, everything in your browser. The compressed figure is measured live in the page and falls back to a labelled estimate on browsers that expose no compression API |
Frequently asked questions
Does this rename my variables?
No. Not one identifier is changed: a function called calculateShippingTotal is still called calculateShippingTotal in the output, and every property name, class name and imported binding is the string you wrote. Renaming is where a real minifier earns most of its saving, and it is also where the risk lives — to shorten a name safely you have to resolve every scope in the file and prove nothing reaches that binding by string, which means eval, with, dynamic property access and anything your framework does by reflection all have to be understood first. This tool does not attempt it, so it cannot get it wrong.
How much smaller will my file actually get?
Between a fifth and a third, and the mix of comments in the file decides where you land. A 2,953-byte module with JSDoc blocks and inline notes came out at 2,059 bytes — 30% off, and 26% off after gzip. The same file with its comments already stripped only lost 20%. For a sense of the ceiling: esbuild, which does rename identifiers and rewrite syntax, took that identical module to 1,664 bytes, or 44%. Those fourteen extra points are precisely the work described in the panel under the tool as not done here.
When should I use a bundler instead of this?
Whenever a build step already exists, use the build step. esbuild, Terser, swc and Rollup rename, drop unreachable branches, inline constants and produce a source map so your stack traces still mean something, and none of that is available from a text box. This page is for the cases with no pipeline in them: a snippet going into a tag manager or a CMS field, an inline script in an email template or a landing page, a userscript, a worker you paste into a dashboard, or a file that has to stay auditable because someone downstream will read what you shipped.
Is the minified file guaranteed to behave the same?
The token stream is identical, which is as close to a guarantee as this kind of tool can give. Every token comes out in the same order with the same text, and only the whitespace between them and the comments around them are gone. The two traps in doing that to JavaScript are both handled: the line break that ends a bare return, throw, break, continue or yield survives the squeeze, since deleting it would hand the statement a value it never had, and two operators are never allowed to fuse — the space in - -a survives, since removing it would turn a double negation into a decrement. If the reader cannot follow the file it hands the original back rather than guessing.
Will it strip console.log, debugger statements or dead branches?
None of the three. A console call is a function call like any other and stays; a debugger statement stays; an if (false) block stays, along with anything inside it. Removing them means knowing what the program does, not just how it is spelled, and that is a different class of tool — the same class that does tree-shaking. If you want a build that drops your logging in production, configure a bundler with a drop option and let it prove the call is unreachable.
What happens to my licence banner?
A comment that begins /*! is kept by default and everything else goes. That convention exists because open-source licences travel with the code: MIT requires the copyright notice and permission notice in all copies, and stripping it from a redistributed bundle is a licence breach rather than an optimisation. The counter tells you how many comments were removed, so if that number looks higher than you expected, check whether a licence header was written with an ordinary /* and give it the exclamation mark before you ship.
Can I minify JSX or TypeScript with it?
You can run them through it and they will come back smaller, but nothing is compiled. A JSX region is copied out verbatim, so the output is still JSX and still needs a transform before a browser will take it; TypeScript annotations survive as ordinary tokens, so the output is still TypeScript. Minifying is not transpiling, and this tool does exactly one of those two jobs. Take the file to your compiler first, then minify the JavaScript that comes out — or skip this and let the compiler do both.
About whitespace-only minification
Minifying JavaScript is really three jobs sold as one. The first is deleting characters the parser ignores: comments, indentation, the newline at the end of every statement. The second is renaming — turning shippingTotal into t everywhere it is in scope. The third is rewriting the program itself: dropping branches that can never run, folding constants, turning true into !0, collapsing an if/else into a ternary. Only the first is safe without a full parse and a scope analysis, and only the first is done here. That is the entire design, and it is why the number in the corner is a third rather than a half.
The trade is worth making in a narrower set of situations than the internet usually admits, so here they are plainly. A snippet pasted into a tag manager, a CMS field or an email template, where no bundler is anywhere in the path. A worker or userscript you edit in a dashboard. Anything you must be able to open in production and recognise — because a file whose names survive can be read by the next person on call, and can be lined up against its source in a diff to prove nothing else changed. When none of those apply and you have a build step, use the build step: it will beat this by fourteen points on the same file and hand you a source map as well.
Two practical notes. Comment-heavy code saves the most, which means a well-documented module loses a third of its bytes while a terse one loses a fifth — the counter tells you which you have. And the raw percentage is not what reaches your user, because whatever your server compresses will already have squeezed the whitespace you just removed; the JSON minifier lays out that arithmetic in detail and the conclusion carries over to scripts. To go the other way — a minified file you need to read rather than ship — the JavaScript formatter puts the lines back.
Where your code is minified
The minifier runs in this tab and the gzip figure is measured there too, so neither your source nor its compressed form is sent anywhere. Nothing in the file is executed either — it is tokenised as text, which is worth knowing when the script you are shrinking came from somewhere you do not entirely trust.