Minify JavaScript: 9 Simple Rules for Best, Safe Output cover image
Prateek Zare

Written by Prateek Zare

Software Developer with ML and Data Expertise, 8+ years of experience

Last updated

Minify JavaScript: 9 Simple Rules for Best, Safe Output

To minify javascript safely, you remove only what the language ignores: comments and whitespace that carry no meaning. Everything else, strings, regex literals and the spaces between keywords, has to survive untouched. This guide gives you nine rules and three lookup tables so you know which is which.

Here is the thing. When people minify javascript and something breaks, the cause is rarely clever optimisation. Most broken minified files do not come from clever optimisation. They come from a plain whitespace removal that did not know it was standing inside a string, a regex or a statement that relied on a line break. The rules below exist to prevent exactly that.

What this guide covers
  1. What it means to minify JavaScript, in real bytes
  2. Nine rules that keep code working
  3. Lookup table: what to remove, keep or reshape
  4. When one space must stay
  5. Stripper or full minifier: which one fits
  6. Before and after, with the real sample
  7. A checklist before release
  8. Related tools

What it means to minify JavaScript, in real bytes

Minification rewrites source so a browser downloads fewer bytes while the program behaves the same. To see the effect, I took a 19 line cart helper with comments, a console call, a regex and a license banner. The numbers below come from that exact file, measured in UTF8 bytes.

459 BOriginal file
284 BAfter stripping comments, whitespace and the console call
38.1%Raw size saved
27.8%Saved after gzip at level 9 (309 to 223 bytes)
Minify javascript test: same file, three measurements
VersionRaw bytesGzip level 9Brotli default
Original with comments459309258
Stripped and minified284223182
Bytes saved175 (38.1%)86 (27.8%)76 (29.5%)

Notice the gap between raw and compressed savings. Compression already squeezes repeated spaces and comment text, so the gain after gzip is smaller. It is still real, and it is the figure your visitors actually feel. Treat the ratios as a guide only, because a 19 line sample behaves differently from a 200 KB bundle.

Nine rules that keep code working

  1. Rule 1: End every statement with a semicolon before you minify javascriptJavaScript lets a newline act as a statement terminator through automatic semicolon insertion. When a minifier joins lines, that newline vanishes. In a test, var a = 1 var b = 2 on one line throws an unexpected token error, while the same two statements on two lines run fine. Add the semicolons in your source, then minify.
  2. Rule 2: Keep one space between word like tokens when you minify javascriptKeywords and identifiers need a separator. return x must not become returnx, and typeof y, else if and a in b follow the same logic. A correct minifier keeps exactly one space when both neighbours could be part of a word or number.
  3. Rule 3: Protect the space in a + +b and a, bIf you squeeze a + +b into a++b, the parser reads an increment operator and fails. The same happens with a--b. The safe output is a+ +b and a- -b, one space kept.
  4. Rule 4: Never edit the inside of a string as you minify javascriptA string such as "Total due: " holds three spaces after Total on purpose. Collapse them and the text on screen changes. Template literals follow the same rule, and their ${ } expressions need brace tracking because an expression can contain braces of its own.
  5. Rule 5: Treat a regex literal like a stringThe body of /\s+\d{2,}/g is pattern syntax, not code. Spaces and comment looking characters inside it matter. The hard part is telling a regex from division: in total / 2 / count both slashes divide. The usual test looks at the last meaningful character before the slash. After an equals sign, an opening bracket, a comma or a semicolon it starts a regex. After a closing parenthesis or a name it divides.
  6. Rule 6: Keep license bannersComments that start with /*! are the convention for license notices. Many open source licenses, MIT included, require the notice to travel with copies of the code. Terser keeps comments that contain @license, @preserve or @copyright, plus any that begin with an exclamation mark, by default. Keep the first banner and drop the rest.
  7. Rule 7: Remove console calls only on purposeStripping debug output is useful, but it is a change of behaviour, not formatting. A call like console.log(i++) has a side effect. A pattern that stops at the first closing parenthesis also mishandles nested calls such as console.log(fmt(a)) spread over several lines. Read the diff after you strip. Terser leaves its drop_console option off unless you ask for it.
  8. Rule 8: Do not rename anything unless the tool understands scopeShortening local variables saves the most bytes and carries the most risk. Code that reads names through eval, with, string keys or the text of a function breaks when names change. A comment and whitespace stripper keeps every name, which is why its savings are modest and its output predictable.
  9. Rule 9: Measure bytes, then run the testsCount UTF8 bytes, not characters. The letter é is one character and two bytes, and an emoji is four bytes. Then run your normal tests against the minified file, not just the source. Keep the original as the file you edit and treat the minified copy as a build artefact.

Lookup table: what to remove, keep or reshape

Use this when you review a minified file or decide how aggressive a tool may be when you minify javascript for production. The right column gives the reason in one line.

Minify javascript token by token decisions
What you findActionReason
Line comment // textRemoveIgnored by the engine
Block comment /* text */RemoveIgnored by the engine
Banner comment /*! text */Keep the first oneLicense notices must travel with the code
Newline between statementsRemove only after a semicolon existsRelies on automatic semicolon insertion otherwise
Spaces around =, +, {, ,RemoveOperators separate tokens by themselves
Space between return and a valueKeep oneTwo words would merge
Text inside quotesKeep exactlySpaces are data
Text inside backticksKeep exactlySpaces and line breaks are data
Regex literal and flagsKeep exactlyPattern syntax is not code
Semicolon before }RemoveThe closing brace ends the statement
Duplicate semicolonsRemoveAn empty statement does nothing
Console callsOptional, review the diffChanges behaviour if arguments have side effects
Variable and function namesKeep in a stripperRenaming needs scope analysis

When one space must stay

Whitespace removal looks simple until two tokens touch. This table lists the pairs that cause real failures, with the safest minified form. I ran each case through a JavaScript engine to confirm the result.

Space survival guide for minify javascript work
SourceMinified formResult
return xreturn xValid, space is required
typeof ytypeof yValid, space is required
a + ba+bValid
a + +ba+ +bValid, evaluates to 3 for 1 and 2
a - -ba- -bValid, evaluates to 7 for 5 and 2
a + +ba++bError: unexpected identifier
var a = 1 then newline var b = 2var a=1 var b=2Error: unexpected token, add the semicolon first
x = y / 2 / zx=y/2/zValid, both slashes divide
The newline trap when you minify javascript

A line that begins with an opening parenthesis, bracket or slash can merge into the line before it. MDN shows a case where const a = 1 followed by (1).toString() is read as one expression. Semicolons in the source remove the whole class of problem, and they are the cheapest habit to adopt before you minify javascript.

Which input needs a change before you minify javascript safely?

The third option relies on a line break to end the first statement. Joined onto one line it becomes a syntax error, so add a semicolon after 5 first. The others are all safe to process.

Stripper or full minifier: which one fits

Two different kinds of tool both get called a minifier. They are not interchangeable, and choosing the right one is part of knowing how to minify javascript for the job in front of you.

Character scan stripper

  • Removes comments, whitespace and optional console calls
  • Keeps every variable and function name
  • Output is easy to predict and compare
  • Good for a single script, a snippet for a CMS or a quick size check
  • Savings are real but modest

AST minifier such as Terser

  • Parses code into a syntax tree before rewriting
  • Mangles names and compresses expressions by default
  • Can remove dead branches and inline constants
  • Belongs in a build pipeline with tests
  • Savings are larger and the risk is higher

For a one off file, a stripper is the fast answer to minify javascript without a build setup. The JS Minifier works this way, scanning one character at a time and tracking whether it sits inside a comment, string, template literal or regex. It does not rename variables, so use a bundler step for production builds.

Paste your script, tick the banner option if you need the license kept, and read the byte savings before you copy it out. Everything runs in your browser.

Open the JS Minifier

Before and after, with the real sample

This is the cart helper from the size table. Compare the two versions line by line and match each change to a rule above.

Minify javascript input: original, 459 bytes

/*! cart.js v1.2 MIT License */
// Cart helpers
function totalPrice(items, taxRate) {
  // add up every line
  var total = 0;
  for (var i = 0; i < items.length; i++) {
    total += items[i].price * items[i].qty;
  }
  console.log("subtotal", total);
  /* apply tax */
  return total * (1 + taxRate);
}

var label = "Total   due:  ";   // keep the spaces
var rx = /\s+\d{2,}/g;
var half = total / 2 / count;
function fmt(n) {
  return label + n.toFixed(2);
}

Minify javascript output: 284 bytes

/*! cart.js v1.2 MIT License */
function totalPrice(items,taxRate){var total=0;for(var i=0;i<items.length;i++){total+=items[i].price*items[i].qty}return total*(1+taxRate)}var label="Total   due:  ";var rx=/\s+\d{2,}/g;var half=total/2/count;function fmt(n){return label+n.toFixed(2)}

The banner survived (rule 6). The three spaces inside the string survived (rule 4). The regex and both divisions are intact (rule 5). The console call is gone (rule 7), and the semicolon before the closing brace of the loop is gone because the brace ends the statement.

A checklist before release

Pre release checks after you minify javascript

Styles weigh bytes too, so run the same idea over your stylesheet with the CSS Minifier. If a pattern misbehaves after minifying, test it first in the Regex Tester. To see exactly what changed between two versions, paste both into the Text Diff Tool.

Short answerTo minify javascript, delete comments, line breaks and spaces around operators. Keep strings, regex literals, license banners and the single space between word like tokens such as return x. Add semicolons first, then check the result by running it.

Questions people ask when they minify javascript

Does it change my code if I minify javascript?

It should not. A correct minifier changes only comments, whitespace and optionally names, so behaviour stays the same. The risk comes from code that depends on line breaks, function names or string contents.

How much smaller will my file get if I minify javascript?

Stripping comments and whitespace saved 38.1 percent on the sample above, and 27.8 percent after gzip. Real files with many comments save more, and files that are already compact save less.

Is it safe to minify JavaScript and remove console.log?

It is safe when the arguments have no side effects. Calls such as console.log(i++) change state, so review the output after removal.

What is the difference between minifying and obfuscating?

Minifying aims at fewer bytes and keeps the program readable to a tool. Obfuscating aims at making the code hard for people to follow. Minified code is not protected, because any formatter restores its layout.

Can I get my original comments back after I minify javascript?

No. Comments and original names are deleted from the output. Keep your source file and generate the minified copy from it each time.

Should I minify javascript if my server already uses gzip or Brotli?

Yes. Compression and minification stack. In the sample, Brotli alone reached 258 bytes and Brotli on the minified file reached 182 bytes.

Sources: Terser, JavaScript parser, mangler and compressor toolkit · MDN, JavaScript lexical grammar