JavaScript Minifier

Global tools

Paste a script and this tool gives you the smallest version of it that still behaves the same way. The scope is deliberately narrow: comments are stripped and runs of spaces and tabs inside a line are collapsed, and that is all. No identifier is renamed, no line break is dropped - an automatic-semicolon-insertion trap - and a script whose string, template or regex never ends is refused with a caret at the opening quote rather than half-processed.

Paste a whole script or a fragment and nothing is truncated. The page starts from a small sample you can replace.

`/*!` comments are the license convention, so they stay by default the way they do in minified files.

Leave it blank for "bundle.js" (or "bundle.min.js").

Results update as you type. Nothing leaves your device.

Minified JavaScript

-21.3%

A conservative pass: it strips comments and the spaces that join nothing. 9 input lines became 9 output lines, and 1 comment went. It never renamed an identifier and never dropped a line break, because both can silently change the program.

Input
207 B
Output
163 B
Saved
44 B
Comments out
1

Minified JavaScript

/*! danfio sample script */
function greeting(name){

return "Hello, "+name+"!";
}
const users=["ada", "grace"];
users.forEach((u)=>{
console.log(greeting(u));
});

Copy it, or download it. The bytes in the box are the bytes in the file.

What was deliberately not done

  • Nothing was renamed: `isEnabled` stays `isEnabled`, because shortening it needs a whole-program analysis this page does not pretend to do.
  • No line break was dropped, even inside braces. Automatic semicolon insertion turns a dropped newline into a changed statement, and one changed statement is a bug.
  • Strings, template literals and regexes are copied verbatim; a URL that looks like a division (`http://…`) is protected by knowing where an expression can start.
  • It shrinks the file, and that is all it promises: dead-code removal and cross-line merging belong to a real minifier.

A conservative minifier is worth using for a specific reason: its output is guaranteed to behave like the input for everything this page accepts, which is exactly what "small, safe, no surprises" means. The page prints what it did not do - no renaming, no dead-code removal, no cross-line merging - because those are the transformations that can silently change a program, and nothing here guesses at them.

About this javascript minifier

A full minifier reads the structure of the program and re-emits it with renamed identifiers, removed dead code and merged statements. This page cannot do any of that without a full reader, so it does the subset that is safe with lexical information alone: strip comments, collapse runs of whitespace inside a line, and re-add the single space that stops two tokens from gluing together.

It keeps every line break, because automatic semicolon insertion treats a newline as a statement separator - dropping one between `let x = 1` and `++x` would silently change the program. Those promises are what "conservative" means here, and they are printed with every result.

Everything happens in the tab: the scan and the rewrite run in JavaScript on the page, so a script - often proprietary or credential-adjacent - never leaves the computer except in the file you download on purpose. The static page already carries a real minified script computed for the page from the sample, so it is useful before anyone has typed. If the honest limit matters to you, the page prints it under every result.

How this javascript minifier works

The two removals, and only the two

`//` line comments and `/* ... */` block comments are stripped, and a leading `/*!` banner is kept on request - the license convention, kept the way minified files keep it. Runs of spaces and tabs inside a line are collapsed to one space. That is the whole removal set, and the results panel counts both: how many comments went and how many bytes.

Nothing else moves. No identifier is renamed, no line break is dropped, and no statement is moved - each of those needs a whole-program analysis this page does not pretend to do, and each can silently change the program (a renamed variable colliding, a dropped newline tripping automatic semicolon insertion).

Why every line break is kept

JavaScript’s automatic semicolon insertion treats a newline as a statement separator in places the source relies on. Dropping a newline between `let x = 1` and `++x` turns two statements into one - `let x = 1 ++x` no longer parses, or worse, parses differently. Keeping every line break costs a byte per line and removes the whole class of bug, so this page keeps them.

The trade is stated openly: a line-oriented minifier cannot merge lines or wrap expressions, so its output is a little larger than a full minifier’s. The guarantee it gives back is that the bytes in the box behave like the bytes that went in.

Strings, templates, regexes - and the one space that saves you

A string, a template literal and a regex are each copied verbatim, because inside them a space can mean something and a `/` is not a division. The scanner tells a regex from a division by asking whether an expression can start at the previous token - after `=`, `(`, `,` or `return`, a `/` begins a regex; after a variable, it divides.

The scanner also re-adds exactly one space where two tokens would otherwise glue together: `a - -b` must not become `a--b`, and `return x` must not become `returnx`. That single space is the difference between a program that still runs and one that means something else.

What is deliberately not done, and when the page refuses

Nothing is renamed, no line break is dropped, no dead code is removed and no statements are merged - those belong to a real minifier that understands the whole program, and the page says so rather than pretending. It shrinks the file, and that is all it promises.

A script whose string, template literal or regex never ends - or whose block comment never closes - is refused with a caret at the opening quote and a sentence about the usual suspects, because laying out half a program would produce output that looks plausible and does not work.

Worked examples

Each example below was run through the calculator on this page when the site was built, so the numbers match what you see when you enter the same inputs.

A script, commented and spaced, made small

Paste your script: /*! (c) 2026 */ function add(a, b) { // the sum return a + b; } const total = add(2, 3); console.log(total);

Minified JavaScript

-17.0%

A conservative pass: it strips comments and the spaces that join nothing. 7 input lines became 7 output lines, and 1 comment went. It never renamed an identifier and never dropped a line break, because both can silently change the program.

Input: 112 B · Output: 93 B · Saved: 19 B · Comments out: 1

The `/*!` banner stays by default and the line comment goes.

A regex literal survives

Paste your script: const re = /a + b/g; const c = a / b; if (m) return x;

Minified JavaScript

-14.8%

A conservative pass: it strips comments and the spaces that join nothing. 3 input lines became 3 output lines, and 0 comments went. It never renamed an identifier and never dropped a line break, because both can silently change the program.

Input: 54 B · Output: 46 B · Saved: 8 B · Comments out: 0

The regex is copied verbatim while the spaces around the division on the next line are tidied.

A script that does not balance is refused

Paste your script: const s = "unterminated;

That script does not balance

line 1

Unterminated string literal

The scanner stops at the opening quote with a caret, and nothing is downloaded.

Frequently asked questions

Is my script uploaded anywhere?

No. The scan and the rewrite run in JavaScript in this tab, the results panel is built from what is already on the page, and the download is a blob created locally. A script is often proprietary or embedded in a product, so nothing here touches a server at all.

Does it rename my variables to short names?

No. Renaming an identifier needs a whole-program analysis - it must prove the new name collides with nothing - and a scanner that cannot do that would rename one occurrence of a flag and leave another, silently changing the program. This page keeps every identifier exactly as written, and says so in the list under the result.

Is the output guaranteed to behave like the input?

Yes, for everything this page accepts. The boundary is why: comments and in-line whitespace are removed, tokens that would glue together gain the one required space, and line breaks, strings, templates, regexes and identifiers are copied verbatim. Those are safe with lexical information alone, so "it shrinks the file" and nothing else is promised or claimed.

Why is a smaller file not always safe to ship?

Because size is not the only axis - behavior is the one that matters. Dropping a line break can trip automatic semicolon insertion, renaming a variable can collide, and merging statements can change evaluation order. A reluctant minifier that keeps line breaks and names is a smaller saving and a much smaller risk, which is the trade this page makes openly.

What happens if my script does not balance?

A script whose string, template literal or regex never closes - or whose block comment never ends - is refused with a caret at the opening quote and a sentence about the usual suspects. Nothing is downloaded, because half a program is not a file you can ship.

Assumptions and sources

  • The cleanup is conservative: it removes comments and extra spaces inside a line, and keeps every line break because JavaScript uses newlines to end statements.
  • Strings, templates and regular expressions are never touched, and a missing closing quote or comment is refused with its line and column.
  • The page does not rename variables or delete code; everything runs in your browser and nothing is uploaded.

Last reviewed 2026-10-07. Runs locally on your device; keep backups; no financial advice applies. Read the full disclaimer.

Where a figure on this page comes from an official agency — HUD, IRS, FICO or a state body — the site keeps a dated snapshot of the source page in its sources library, and a scheduled job re-checks that snapshot, so the number can be traced back to the document it came from.