4 UglifyJS is a JavaScript parser, minifier, compressor and beautifier toolkit.
7 - `uglify-js` supports JavaScript and most language features in ECMAScript.
8 - For more exotic parts of ECMAScript, process your source file with transpilers
9 like [Babel](https://babeljs.io/) before passing onto `uglify-js`.
10 - `uglify-js@3` has a simplified [API](#api-reference) and [CLI](#command-line-usage)
11 that is not backwards compatible with [`uglify-js@2`](https://github.com/mishoo/UglifyJS/tree/v2.x).
16 First make sure you have installed the latest version of [node.js](http://nodejs.org/)
17 (You may need to restart your computer after this step).
19 From NPM for use as a command line app:
21 npm install uglify-js -g
23 From NPM for programmatic use:
29 uglifyjs [input files] [options]
31 UglifyJS can take multiple input files. It's recommended that you pass the
32 input files first, then pass the options. UglifyJS will parse input files
33 in sequence and apply any compression options. The files are parsed in the
34 same global scope, that is, a reference from a file to some
35 variable/function declared in another file will be matched properly.
37 If no input file is specified, UglifyJS will read from STDIN.
39 If you wish to pass your options before the input files, separate the two with
40 a double dash to prevent input files being used as option arguments:
42 uglifyjs --compress --mangle -- input.js
44 ### Command line options
47 -h, --help Print usage information.
48 `--help options` for details on available options.
49 -V, --version Print version number.
50 -p, --parse <options> Specify parser options:
51 `acorn` Use Acorn for parsing.
52 `bare_returns` Allow return outside of functions.
53 Useful when minifying CommonJS
54 modules and Userscripts that may
55 be anonymous function wrapped (IIFE)
56 by the .user.js engine `caller`.
57 `expression` Parse a single expression, rather than
58 a program (for parsing JSON).
59 `spidermonkey` Assume input files are SpiderMonkey
61 -c, --compress [options] Enable compressor/specify compressor options:
62 `pure_funcs` List of functions that can be safely
63 removed when their return values are
65 -m, --mangle [options] Mangle names/specify mangler options:
66 `reserved` List of names that should not be mangled.
67 --mangle-props [options] Mangle properties/specify mangler options:
68 `builtins` Mangle property names that overlaps
69 with standard JavaScript globals.
70 `debug` Add debug prefix and suffix.
71 `domprops` Mangle property names that overlaps
73 `keep_quoted` Only mangle unquoted properties.
74 `regex` Only mangle matched property names.
75 `reserved` List of names that should not be mangled.
76 -b, --beautify [options] Beautify output/specify output options:
77 `beautify` Enabled with `--beautify` by default.
78 `preamble` Preamble to prepend to the output. You
79 can use this to insert a comment, for
80 example for licensing information.
81 This will not be parsed, but the source
82 map will adjust for its presence.
83 `quote_style` Quote style:
88 `wrap_iife` Wrap IIFEs in parentheses. Note: you may
89 want to disable `negate_iife` under
91 -O, --output-opts [options] Specify output options (`beautify` disabled by default).
92 -o, --output <file> Output file path (default STDOUT). Specify `ast` or
93 `spidermonkey` to write UglifyJS or SpiderMonkey AST
94 as JSON to STDOUT respectively.
95 --annotations Process and preserve comment annotations.
96 (`/*@__PURE__*/` or `/*#__PURE__*/`)
97 --no-annotations Ignore and discard comment annotations.
98 --comments [filter] Preserve copyright comments in the output. By
99 default this works like Google Closure, keeping
100 JSDoc-style comments that contain "@license" or
101 "@preserve". You can optionally pass one of the
102 following arguments to this flag:
103 - "all" to keep all comments
104 - a valid JS RegExp like `/foo/` or `/^!/` to
105 keep only matching comments.
106 Note that currently not *all* comments can be
107 kept when compression is on, because of dead
108 code removal or cascading statements into
110 --config-file <file> Read `minify()` options from JSON file.
111 -d, --define <expr>[=value] Global definitions.
112 -e, --enclose [arg[:value]] Embed everything in a big function, with configurable
113 argument(s) & value(s).
114 --ie Support non-standard Internet Explorer.
115 Equivalent to setting `ie: true` in `minify()`
116 for `compress`, `mangle` and `output` options.
117 By default UglifyJS will not try to be IE-proof.
118 --keep-fnames Do not mangle/drop function names. Useful for
119 code relying on Function.prototype.name.
120 --name-cache <file> File to hold mangled name mappings.
121 --self Build UglifyJS as a library (implies --wrap UglifyJS)
122 --source-map [options] Enable source map/specify source map options:
123 `base` Path to compute relative paths from input files.
124 `content` Input source map, useful if you're compressing
125 JS that was generated from some other original
126 code. Specify "inline" if the source map is
127 included within the sources.
128 `filename` Filename and/or location of the output source
129 (sets `file` attribute in source map).
130 `includeSources` Pass this flag if you want to include
131 the content of source files in the
132 source map as sourcesContent property.
133 `names` Include symbol names in the source map.
134 `root` Path to the original source to be included in
136 `url` If specified, path to the source map to append in
137 `//# sourceMappingURL`.
138 --timings Display operations run time on STDERR.
139 --toplevel Compress and/or mangle variables in top level scope.
140 --v8 Support non-standard Chrome & Node.js
141 Equivalent to setting `v8: true` in `minify()`
142 for `mangle` and `output` options.
143 By default UglifyJS will not try to be v8-proof.
144 --verbose Print diagnostic messages.
145 --warn Print warning messages.
146 --webkit Support non-standard Safari/Webkit.
147 Equivalent to setting `webkit: true` in `minify()`
148 for `mangle` and `output` options.
149 By default UglifyJS will not try to be Safari-proof.
150 --wrap <name> Embed everything in a big function, making the
151 “exports” and “global” variables available. You
152 need to pass an argument to this option to
153 specify the name that your module will take
154 when included in, say, a browser.
157 Specify `--output` (`-o`) to declare the output file. Otherwise the output
160 ## CLI source map options
162 UglifyJS can generate a source map file, which is highly useful for
163 debugging your compressed JavaScript. To get a source map, pass
164 `--source-map --output output.js` (source map will be written out to
169 - `--source-map "filename='<NAME>'"` to specify the name of the source map. The value of
170 `filename` is only used to set `file` attribute (see [the spec][sm-spec])
173 - `--source-map "root='<URL>'"` to pass the URL where the original files can be found.
175 - `--source-map "names=false"` to omit symbol names if you want to reduce size
176 of the source map file.
178 - `--source-map "url='<URL>'"` to specify the URL where the source map can be found.
179 Otherwise UglifyJS assumes HTTP `X-SourceMap` is being used and will omit the
180 `//# sourceMappingURL=` directive.
184 uglifyjs js/file1.js js/file2.js \
185 -o foo.min.js -c -m \
186 --source-map "root='http://foo.com/src',url='foo.min.js.map'"
188 The above will compress and mangle `file1.js` and `file2.js`, will drop the
189 output in `foo.min.js` and the source map in `foo.min.js.map`. The source
190 mapping will refer to `http://foo.com/src/js/file1.js` and
191 `http://foo.com/src/js/file2.js` (in fact it will list `http://foo.com/src`
192 as the source map root, and the original files as `js/file1.js` and
195 ### Composed source map
197 When you're compressing JS code that was output by a compiler such as
198 CoffeeScript, mapping to the JS code won't be too helpful. Instead, you'd
199 like to map back to the original code (i.e. CoffeeScript). UglifyJS has an
200 option to take an input source map. Assuming you have a mapping from
201 CoffeeScript → compiled JS, UglifyJS can generate a map from CoffeeScript →
202 compressed JS by mapping every token in the compiled JS to its original
205 To use this feature pass `--source-map "content='/path/to/input/source.map'"`
206 or `--source-map "content=inline"` if the source map is included inline with
209 ## CLI compress options
211 You need to pass `--compress` (`-c`) to enable the compressor. Optionally
212 you can pass a comma-separated list of [compress options](#compress-options).
214 Options are in the form `foo=bar`, or just `foo` (the latter implies
215 a boolean option that you want to set `true`; it's effectively a
216 shortcut for `foo=true`).
220 uglifyjs file.js -c toplevel,sequences=false
222 ## CLI mangle options
224 To enable the mangler you need to pass `--mangle` (`-m`). The following
225 (comma-separated) options are supported:
227 - `eval` (default: `false`) — mangle names visible in scopes where `eval` or
230 - `reserved` (default: `[]`) — when mangling is enabled but you want to
231 prevent certain names from being mangled, you can declare those names with
232 `--mangle reserved` — pass a comma-separated list of names. For example:
234 uglifyjs ... -m reserved=['$','require','exports']
236 to prevent the `require`, `exports` and `$` names from being changed.
238 ### CLI mangling property names (`--mangle-props`)
240 **Note:** THIS WILL PROBABLY BREAK YOUR CODE. Mangling property names
241 is a separate step, different from variable name mangling. Pass
242 `--mangle-props` to enable it. It will mangle all properties in the
243 input code with the exception of built in DOM properties and properties
244 in core JavaScript classes. For example:
252 return this.foo_ + this.baz_;
257 console.log(x.calc());
259 Mangle all properties (except for JavaScript `builtins`):
261 $ uglifyjs example.js -c -m --mangle-props
264 var x={o:0,_:1,l:function(){return this._+this.o}};x.t=2,x.o=3,console.log(x.l());
266 Mangle all properties except for `reserved` properties:
268 $ uglifyjs example.js -c -m --mangle-props reserved=[foo_,bar_]
271 var x={o:0,foo_:1,_:function(){return this.foo_+this.o}};x.bar_=2,x.o=3,console.log(x._());
273 Mangle all properties matching a `regex`:
275 $ uglifyjs example.js -c -m --mangle-props regex=/_$/
278 var x={o:0,_:1,calc:function(){return this._+this.o}};x.l=2,x.o=3,console.log(x.calc());
281 Combining mangle properties options:
283 $ uglifyjs example.js -c -m --mangle-props regex=/_$/,reserved=[bar_]
286 var x={o:0,_:1,calc:function(){return this._+this.o}};x.bar_=2,x.o=3,console.log(x.calc());
289 In order for this to be of any use, we avoid mangling standard JS names by
290 default (`--mangle-props builtins` to override).
292 A default exclusion file is provided in `tools/domprops.json` which should
293 cover most standard JS and DOM properties defined in various browsers. Pass
294 `--mangle-props domprops` to disable this feature.
296 A regular expression can be used to define which property names should be
297 mangled. For example, `--mangle-props regex=/^_/` will only mangle property
298 names that start with an underscore.
300 When you compress multiple files using this option, in order for them to
301 work together in the end we need to ensure somehow that one property gets
302 mangled to the same name in all of them. For this, pass `--name-cache filename.json`
303 and UglifyJS will maintain these mappings in a file which can then be reused.
304 It should be initially empty. Example:
307 $ rm -f /tmp/cache.json # start fresh
308 $ uglifyjs file1.js file2.js --mangle-props --name-cache /tmp/cache.json -o part1.js
309 $ uglifyjs file3.js file4.js --mangle-props --name-cache /tmp/cache.json -o part2.js
312 Now, `part1.js` and `part2.js` will be consistent with each other in terms
313 of mangled property names.
315 Using the name cache is not necessary if you compress all your files in a
316 single call to UglifyJS.
318 ### Mangling unquoted names (`--mangle-props keep_quoted`)
320 Using quoted property name (`o["foo"]`) reserves the property name (`foo`)
321 so that it is not mangled throughout the entire script even when used in an
322 unquoted style (`o.foo`). Example:
334 $ uglifyjs stuff.js --mangle-props keep_quoted -c -m
337 var o={foo:1,o:3};o.foo+=o.o,console.log(o.foo);
340 ### Debugging property name mangling
342 You can also pass `--mangle-props debug` in order to mangle property names
343 without completely obscuring them. For example the property `o.foo`
344 would mangle to `o._$foo$_` with this option. This allows property mangling
345 of a large codebase while still being able to debug the code and identify
346 where mangling is breaking things.
349 $ uglifyjs stuff.js --mangle-props debug -c -m
352 var o={_$foo$_:1,_$bar$_:3};o._$foo$_+=o._$bar$_,console.log(o._$foo$_);
355 You can also pass a custom suffix using `--mangle-props debug=XYZ`. This would then
356 mangle `o.foo` to `o._$foo$XYZ_`. You can change this each time you compile a
357 script to identify how a property got mangled. One technique is to pass a
358 random number on every compile to simulate mangling changing with different
359 inputs (e.g. as you update the input script with new properties), and to help
360 identify mistakes like writing mangled keys to storage.
365 Assuming installation via NPM, you can load UglifyJS in your application
368 var UglifyJS = require("uglify-js");
371 There is a single high level function, **`minify(code, options)`**,
372 which will perform all minification [phases](#minify-options) in a configurable
373 manner. By default `minify()` will enable the options [`compress`](#compress-options)
374 and [`mangle`](#mangle-options). Example:
376 var code = "function add(first, second) { return first + second; }";
377 var result = UglifyJS.minify(code);
378 console.log(result.error); // runtime error, or `undefined` if no error
379 console.log(result.code); // minified output: function add(n,d){return n+d}
382 You can `minify` more than one JavaScript file at a time by using an object
383 for the first argument where the keys are file names and the values are source
387 "file1.js": "function add(first, second) { return first + second; }",
388 "file2.js": "console.log(add(1 + 2, 3 + 4));"
390 var result = UglifyJS.minify(code);
391 console.log(result.code);
392 // function add(d,n){return d+n}console.log(add(3,7));
395 The `toplevel` option:
398 "file1.js": "function add(first, second) { return first + second; }",
399 "file2.js": "console.log(add(1 + 2, 3 + 4));"
401 var options = { toplevel: true };
402 var result = UglifyJS.minify(code, options);
403 console.log(result.code);
407 The `nameCache` option:
415 var result1 = UglifyJS.minify({
416 "file1.js": "function add(first, second) { return first + second; }"
418 var result2 = UglifyJS.minify({
419 "file2.js": "console.log(add(1 + 2, 3 + 4));"
421 console.log(result1.code);
422 // function n(n,r){return n+r}
423 console.log(result2.code);
424 // console.log(n(3,7));
427 You may persist the name cache to the file system in the following way:
429 var cacheFileName = "/tmp/cache.json";
434 nameCache: JSON.parse(fs.readFileSync(cacheFileName, "utf8"))
436 fs.writeFileSync("part1.js", UglifyJS.minify({
437 "file1.js": fs.readFileSync("file1.js", "utf8"),
438 "file2.js": fs.readFileSync("file2.js", "utf8")
439 }, options).code, "utf8");
440 fs.writeFileSync("part2.js", UglifyJS.minify({
441 "file3.js": fs.readFileSync("file3.js", "utf8"),
442 "file4.js": fs.readFileSync("file4.js", "utf8")
443 }, options).code, "utf8");
444 fs.writeFileSync(cacheFileName, JSON.stringify(options.nameCache), "utf8");
447 An example of a combination of `minify()` options:
450 "file1.js": "function add(first, second) { return first + second; }",
451 "file2.js": "console.log(add(1 + 2, 3 + 4));"
457 "@console.log": "alert"
463 preamble: "/* uglified */"
466 var result = UglifyJS.minify(code, options);
467 console.log(result.code);
474 var code = "function f(){ var u; return 2 + 3; }";
475 var options = { warnings: true };
476 var result = UglifyJS.minify(code, options);
477 console.log(result.error); // runtime error, `undefined` in this case
478 console.log(result.warnings); // [ 'Dropping unused variable u [0:1,18]' ]
479 console.log(result.code); // function f(){return 5}
484 var result = UglifyJS.minify({"foo.js" : "if (0) else console.log(1);"});
485 console.log(JSON.stringify(result.error));
486 // {"message":"Unexpected token: keyword (else)","filename":"foo.js","line":1,"col":7,"pos":7}
488 Note: unlike `uglify-js@2.x`, the `3.x` API does not throw errors. To
489 achieve a similar effect one could do the following:
491 var result = UglifyJS.minify(code, options);
492 if (result.error) throw result.error;
497 - `annotations` — pass `false` to ignore all comment annotations and elide them
498 from output. Useful when, for instance, external tools incorrectly applied
499 `/*@__PURE__*/` or `/*#__PURE__*/`. Pass `true` to both compress and retain
500 comment annotations in output to allow for further processing downstream.
502 - `compress` (default: `{}`) — pass `false` to skip compressing entirely.
503 Pass an object to specify custom [compress options](#compress-options).
505 - `ie` (default: `false`) — enable workarounds for Internet Explorer bugs.
507 - `keep_fnames` (default: `false`) — pass `true` to prevent discarding or mangling
508 of function names. Useful for code relying on `Function.prototype.name`.
510 - `mangle` (default: `true`) — pass `false` to skip mangling names, or pass
511 an object to specify [mangle options](#mangle-options) (see below).
513 - `mangle.properties` (default: `false`) — a subcategory of the mangle option.
514 Pass an object to specify custom [mangle property options](#mangle-properties-options).
516 - `nameCache` (default: `null`) — pass an empty object `{}` or a previously
517 used `nameCache` object if you wish to cache mangled variable and
518 property names across multiple invocations of `minify()`. Note: this is
519 a read/write property. `minify()` will read the name cache state of this
520 object and update it during minification so that it may be
521 reused or externally persisted by the user.
523 - `output` (default: `null`) — pass an object if you wish to specify
524 additional [output options](#output-options). The defaults are optimized
525 for best compression.
527 - `parse` (default: `{}`) — pass an object if you wish to specify some
528 additional [parse options](#parse-options).
530 - `sourceMap` (default: `false`) — pass an object if you wish to specify
531 [source map options](#source-map-options).
533 - `toplevel` (default: `false`) — set to `true` if you wish to enable top level
534 variable and function name mangling and to drop unused variables and functions.
536 - `v8` (default: `false`) — enable workarounds for Chrome & Node.js bugs.
538 - `warnings` (default: `false`) — pass `true` to return compressor warnings
539 in `result.warnings`. Use the value `"verbose"` for more detailed warnings.
541 - `webkit` (default: `false`) — enable workarounds for Safari/WebKit bugs.
542 PhantomJS users should set this option to `true`.
544 ## Minify options structure
558 // mangle property options
565 // source map options
567 nameCache: null, // or specify a name cache object
573 ### Source map options
575 To generate a source map:
577 var result = UglifyJS.minify({"file1.js": "var a = function() {};"}, {
583 console.log(result.code); // minified output
584 console.log(result.map); // source map
587 Note that the source map is not saved in a file, it's just returned in
588 `result.map`. The value passed for `sourceMap.url` is only used to set
589 `//# sourceMappingURL=out.js.map` in `result.code`. The value of
590 `filename` is only used to set `file` attribute (see [the spec][sm-spec])
593 You can set option `sourceMap.url` to be `"inline"` and source map will
596 You can also specify sourceRoot property to be included in source map:
598 var result = UglifyJS.minify({"file1.js": "var a = function() {};"}, {
600 root: "http://example.com/src",
606 If you're compressing compiled JavaScript and have a source map for it, you
607 can use `sourceMap.content`:
609 var result = UglifyJS.minify({"compiled.js": "compiled code"}, {
611 content: "content from compiled.js.map",
612 url: "minified.js.map"
615 // same as before, it returns `code` and `map`
618 If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.url`.
620 If you wish to reduce file size of the source map, set option `sourceMap.names`
621 to be `false` and all symbol names will be omitted.
625 - `bare_returns` (default: `false`) — support top level `return` statements
627 - `html5_comments` (default: `true`)
629 - `shebang` (default: `true`) — support `#!command` as the first line
633 - `annotations` (default: `true`) — Pass `false` to disable potentially dropping
634 functions marked as "pure". A function call is marked as "pure" if a comment
635 annotation `/*@__PURE__*/` or `/*#__PURE__*/` immediately precedes the call. For
636 example: `/*@__PURE__*/foo();`
638 - `arguments` (default: `true`) — replace `arguments[index]` with function
639 parameter name whenever possible.
641 - `arrows` (default: `true`) — apply optimizations to arrow functions
643 - `assignments` (default: `true`) — apply optimizations to assignment expressions
645 - `awaits` (default: `true`) — apply optimizations to `await` expressions
647 - `booleans` (default: `true`) — various optimizations for boolean context,
648 for example `!!a ? b : c → a ? b : c`
650 - `collapse_vars` (default: `true`) — Collapse single-use non-constant variables,
651 side effects permitting.
653 - `comparisons` (default: `true`) — apply certain optimizations to binary nodes,
654 e.g. `!(a <= b) → a > b`, attempts to negate binary nodes, e.g.
655 `a = !b && !c && !d && !e → a=!(b||c||d||e)` etc.
657 - `conditionals` (default: `true`) — apply optimizations for `if`-s and conditional
660 - `dead_code` (default: `true`) — remove unreachable code
662 - `default_values` (default: `true`) — drop overshadowed default values
664 - `directives` (default: `true`) — remove redundant or non-standard directives
666 - `drop_console` (default: `false`) — Pass `true` to discard calls to
667 `console.*` functions. If you wish to drop a specific function call
668 such as `console.info` and/or retain side effects from function arguments
669 after dropping the function call then use `pure_funcs` instead.
671 - `drop_debugger` (default: `true`) — remove `debugger;` statements
673 - `evaluate` (default: `true`) — Evaluate expression for shorter constant
674 representation. Pass `"eager"` to always replace function calls whenever
675 possible, or a positive integer to specify an upper bound for each individual
676 evaluation in number of characters.
678 - `expression` (default: `false`) — Pass `true` to preserve completion values
679 from terminal statements without `return`, e.g. in bookmarklets.
681 - `functions` (default: `true`) — convert declarations from `var` to `function`
684 - `global_defs` (default: `{}`) — see [conditional compilation](#conditional-compilation)
686 - `hoist_exports` (default: `true`) — hoist `export` statements to facilitate
687 various `compress` and `mangle` optimizations.
689 - `hoist_funs` (default: `false`) — hoist function declarations
691 - `hoist_props` (default: `true`) — hoist properties from constant object and
692 array literals into regular variables subject to a set of constraints. For example:
693 `var o={p:1, q:2}; f(o.p, o.q);` is converted to `f(1, 2);`. Note: `hoist_props`
694 works best with `toplevel` and `mangle` enabled, alongside with `compress` option
695 `passes` set to `2` or higher.
697 - `hoist_vars` (default: `false`) — hoist `var` declarations (this is `false`
698 by default because it seems to increase the size of the output in general)
700 - `if_return` (default: `true`) — optimizations for if/return and if/continue
702 - `imports` (default: `true`) — drop unreferenced import symbols when used with `unused`
704 - `inline` (default: `true`) — inline calls to function with simple/`return` statement:
705 - `false` — same as `0`
706 - `0` — disabled inlining
707 - `1` — inline simple functions
708 - `2` — inline functions with arguments
709 - `3` — inline functions with arguments and variables
710 - `4` — inline functions with arguments, variables and statements
711 - `true` — same as `4`
713 - `join_vars` (default: `true`) — join consecutive `var` statements
715 - `keep_fargs` (default: `false`) — discard unused function arguments except
716 when unsafe to do so, e.g. code which relies on `Function.prototype.length`.
717 Pass `true` to always retain function arguments.
719 - `keep_infinity` (default: `false`) — Pass `true` to prevent `Infinity` from
720 being compressed into `1/0`, which may cause performance issues on Chrome.
722 - `loops` (default: `true`) — optimizations for `do`, `while` and `for` loops
723 when we can statically determine the condition.
725 - `merge_vars` (default: `true`) — combine and reuse variables.
727 - `negate_iife` (default: `true`) — negate "Immediately-Called Function Expressions"
728 where the return value is discarded, to avoid the parens that the
729 code generator would insert.
731 - `objects` (default: `true`) — compact duplicate keys in object literals.
733 - `passes` (default: `1`) — The maximum number of times to run compress.
734 In some cases more than one pass leads to further compressed code. Keep in
735 mind more passes will take more time.
737 - `properties` (default: `true`) — rewrite property access using the dot notation, for
738 example `foo["bar"] → foo.bar`
740 - `pure_funcs` (default: `null`) — You can pass an array of names and
741 UglifyJS will assume that those functions do not produce side
742 effects. DANGER: will not check if the name is redefined in scope.
743 An example case here, for instance `var q = Math.floor(a/b)`. If
744 variable `q` is not used elsewhere, UglifyJS will drop it, but will
745 still keep the `Math.floor(a/b)`, not knowing what it does. You can
746 pass `pure_funcs: [ 'Math.floor' ]` to let it know that this
747 function won't produce any side effect, in which case the whole
748 statement would get discarded. The current implementation adds some
749 overhead (compression will be slower). Make sure symbols under `pure_funcs`
750 are also under `mangle.reserved` to avoid mangling.
752 - `pure_getters` (default: `"strict"`) — If you pass `true` for
753 this, UglifyJS will assume that object property access
754 (e.g. `foo.bar` or `foo["bar"]`) doesn't have any side effects.
755 Specify `"strict"` to treat `foo.bar` as side-effect-free only when
756 `foo` is certain to not throw, i.e. not `null` or `undefined`.
758 - `reduce_funcs` (default: `true`) — Allows single-use functions to be
759 inlined as function expressions when permissible allowing further
760 optimization. Enabled by default. Option depends on `reduce_vars`
761 being enabled. Some code runs faster in the Chrome V8 engine if this
762 option is disabled. Does not negatively impact other major browsers.
764 - `reduce_vars` (default: `true`) — Improve optimization on variables assigned with and
765 used as constant values.
767 - `rests` (default: `true`) — apply optimizations to rest parameters
769 - `sequences` (default: `true`) — join consecutive simple statements using the
770 comma operator. May be set to a positive integer to specify the maximum number
771 of consecutive comma sequences that will be generated. If this option is set to
772 `true` then the default `sequences` limit is `200`. Set option to `false` or `0`
773 to disable. The smallest `sequences` length is `2`. A `sequences` value of `1`
774 is grandfathered to be equivalent to `true` and as such means `200`. On rare
775 occasions the default sequences limit leads to very slow compress times in which
776 case a value of `20` or less is recommended.
778 - `side_effects` (default: `true`) — drop extraneous code which does not affect
779 outcome of runtime execution.
781 - `spreads` (default: `true`) — flatten spread expressions.
783 - `strings` (default: `true`) — compact string concatenations.
785 - `switches` (default: `true`) — de-duplicate and remove unreachable `switch` branches
787 - `templates` (default: `true`) — compact template literals by embedding expressions
788 and/or converting to string literals, e.g. `` `foo ${42}` → "foo 42"``
790 - `top_retain` (default: `null`) — prevent specific toplevel functions and
791 variables from `unused` removal (can be array, comma-separated, RegExp or
792 function. Implies `toplevel`)
794 - `toplevel` (default: `false`) — drop unreferenced functions (`"funcs"`) and/or
795 variables (`"vars"`) in the top level scope (`false` by default, `true` to drop
796 both unreferenced functions and variables)
798 - `typeofs` (default: `true`) — compress `typeof` expressions, e.g.
799 `typeof foo == "undefined" → void 0 === foo`
801 - `unsafe` (default: `false`) — apply "unsafe" transformations (discussion below)
803 - `unsafe_comps` (default: `false`) — compress expressions like `a <= b` assuming
804 none of the operands can be (coerced to) `NaN`.
806 - `unsafe_Function` (default: `false`) — compress and mangle `Function(args, code)`
807 when both `args` and `code` are string literals.
809 - `unsafe_math` (default: `false`) — optimize numerical expressions like
810 `2 * x * 3` into `6 * x`, which may give imprecise floating point results.
812 - `unsafe_proto` (default: `false`) — optimize expressions like
813 `Array.prototype.slice.call(a)` into `[].slice.call(a)`
815 - `unsafe_regexp` (default: `false`) — enable substitutions of variables with
816 `RegExp` values the same way as if they are constants.
818 - `unsafe_undefined` (default: `false`) — substitute `void 0` if there is a
819 variable named `undefined` in scope (variable name will be mangled, typically
820 reduced to a single character)
822 - `unused` (default: `true`) — drop unreferenced functions and variables (simple
823 direct variable assignments do not count as references unless set to `"keep_assign"`)
825 - `varify` (default: `true`) — convert block-scoped declaractions into `var`
826 whenever safe to do so
828 - `yields` (default: `true`) — apply optimizations to `yield` expressions
832 - `eval` (default: `false`) — Pass `true` to mangle names visible in scopes
833 where `eval` or `with` are used.
835 - `reserved` (default: `[]`) — Pass an array of identifiers that should be
836 excluded from mangling. Example: `["foo", "bar"]`.
838 - `toplevel` (default: `false`) — Pass `true` to mangle names declared in the
846 function funcName(firstLongName, anotherLongName) {
847 var myVariable = firstLongName + anotherLongName;
851 var code = fs.readFileSync("test.js", "utf8");
853 UglifyJS.minify(code).code;
854 // 'function funcName(a,n){}var globalVar;'
856 UglifyJS.minify(code, { mangle: { reserved: ['firstLongName'] } }).code;
857 // 'function funcName(firstLongName,a){}var globalVar;'
859 UglifyJS.minify(code, { mangle: { toplevel: true } }).code;
860 // 'function n(n,a){}var a;'
863 ### Mangle properties options
865 - `builtins` (default: `false`) — Use `true` to allow the mangling of builtin
866 DOM properties. Not recommended to override this setting.
868 - `debug` (default: `false`) — Mangle names with the original name still present.
869 Pass an empty string `""` to enable, or a non-empty string to set the debug suffix.
871 - `keep_quoted` (default: `false`) — Only mangle unquoted property names.
873 - `regex` (default: `null`) — Pass a RegExp literal to only mangle property
874 names matching the regular expression.
876 - `reserved` (default: `[]`) — Do not mangle property names listed in the
881 The code generator tries to output shortest code possible by default. In
882 case you want beautified output, pass `--beautify` (`-b`). Optionally you
883 can pass additional arguments that control the code output:
885 - `annotations` (default: `false`) — pass `true` to retain comment annotations
886 `/*@__PURE__*/` or `/*#__PURE__*/`, otherwise they will be discarded even if
889 - `ascii_only` (default: `false`) — escape Unicode characters in strings and
890 regexps (affects directives with non-ascii characters becoming invalid)
892 - `beautify` (default: `true`) — whether to actually beautify the output.
893 Passing `-b` will set this to true, but you might need to pass `-b` even
894 when you want to generate minified code, in order to specify additional
895 arguments, so you can use `-b beautify=false` to override it.
897 - `braces` (default: `false`) — always insert braces in `if`, `for`,
898 `do`, `while` or `with` statements, even if their body is a single
901 - `comments` (default: `false`) — pass `true` or `"all"` to preserve all
902 comments, `"some"` to preserve multi-line comments that contain `@cc_on`,
903 `@license`, or `@preserve` (case-insensitive), a regular expression string
904 (e.g. `/^!/`), or a function which returns `boolean`, e.g.
906 function(node, comment) {
907 return comment.value.indexOf("@type " + node.TYPE) >= 0;
911 - `galio` (default: `false`) — enable workarounds for ANT Galio bugs
913 - `indent_level` (default: `4`)
915 - `indent_start` (default: `0`) — prefix all lines by that many spaces
917 - `inline_script` (default: `true`) — escape HTML comments and the slash in
918 occurrences of `</script>` in strings
920 - `keep_quoted_props` (default: `false`) — when turned on, prevents stripping
921 quotes from property names in object literals.
923 - `max_line_len` (default: `false`) — maximum line length (for uglified code)
925 - `preamble` (default: `null`) — when passed it must be a string and
926 it will be prepended to the output literally. The source map will
927 adjust for this text. Can be used to insert a comment containing
928 licensing information, for example.
930 - `preserve_line` (default: `false`) — pass `true` to retain line numbering on
933 - `quote_keys` (default: `false`) — pass `true` to quote all keys in literal
936 - `quote_style` (default: `0`) — preferred quote style for strings (affects
937 quoted property names and directives as well):
938 - `0` — prefers double quotes, switches to single quotes when there are
939 more double quotes in the string itself. `0` is best for gzip size.
940 - `1` — always use single quotes
941 - `2` — always use double quotes
942 - `3` — always use the original quotes
944 - `semicolons` (default: `true`) — separate statements with semicolons. If
945 you pass `false` then whenever possible we will use a newline instead of a
946 semicolon, leading to more readable output of uglified code (size before
947 gzip could be smaller; size after gzip insignificantly larger).
949 - `shebang` (default: `true`) — preserve shebang `#!` in preamble (bash scripts)
951 - `width` (default: `80`) — only takes effect when beautification is on, this
952 specifies an (orientative) line width that the beautifier will try to
953 obey. It refers to the width of the line text (excluding indentation).
954 It doesn't work very well currently, but it does make the code generated
955 by UglifyJS more readable.
957 - `wrap_iife` (default: `false`) — pass `true` to wrap immediately invoked
958 function expressions. See
959 [#640](https://github.com/mishoo/UglifyJS/issues/640) for more details.
963 ### Keeping copyright notices or other comments
965 You can pass `--comments` to retain certain comments in the output. By
966 default it will keep JSDoc-style comments that contain "@preserve",
967 "@license" or "@cc_on" (conditional compilation for IE). You can pass
968 `--comments all` to keep all the comments, or a valid JavaScript regexp to
969 keep only comments that match this regexp. For example `--comments /^!/`
970 will keep comments like `/*! Copyright Notice */`.
972 Note, however, that there might be situations where comments are lost. For
976 /** @preserve Foo Bar */
978 // this function is never called
984 Even though it has "@preserve", the comment will be lost because the inner
985 function `g` (which is the AST node to which the comment is attached to) is
986 discarded by the compressor as not referenced.
988 The safest comments where to place copyright information (or other info that
989 needs to be kept in the output) are comments attached to toplevel nodes.
991 ### The `unsafe` `compress` option
993 It enables some transformations that *might* break code logic in certain
994 contrived cases, but should be fine for most code. You might want to try it
995 on your own code, it should reduce the minified size. Here's what happens
996 when this flag is on:
998 - `new Array(1, 2, 3)` or `Array(1, 2, 3)` → `[ 1, 2, 3 ]`
999 - `new Object()` → `{}`
1000 - `String(exp)` or `exp.toString()` → `"" + exp`
1001 - `new Object/RegExp/Function/Error/Array (...)` → we discard the `new`
1003 ### Conditional compilation
1005 You can use the `--define` (`-d`) switch in order to declare global
1006 variables that UglifyJS will assume to be constants (unless defined in
1007 scope). For example if you pass `--define DEBUG=false` then, coupled with
1008 dead code removal UglifyJS will discard the following from the output:
1011 console.log("debug stuff");
1015 You can specify nested constants in the form of `--define env.DEBUG=false`.
1017 UglifyJS will warn about the condition being always false and about dropping
1018 unreachable code; for now there is no option to turn off only this specific
1019 warning, you can pass `warnings=false` to turn off *all* warnings.
1021 Another way of doing that is to declare your globals as constants in a
1022 separate file and include it into the build. For example you can have a
1023 `build/defines.js` file with the following:
1026 var PRODUCTION = true;
1030 and build your code like this:
1032 uglifyjs build/defines.js js/foo.js js/bar.js... -c
1034 UglifyJS will notice the constants and, since they cannot be altered, it
1035 will evaluate references to them to the value itself and drop unreachable
1036 code as usual. The build will contain the `const` declarations if you use
1037 them. If you are targeting < ES6 environments which does not support `const`,
1038 using `var` with `reduce_vars` (enabled by default) should suffice.
1040 ### Conditional compilation API
1042 You can also use conditional compilation via the programmatic API. With the difference that the
1043 property name is `global_defs` and is a compressor property:
1046 var result = UglifyJS.minify(fs.readFileSync("input.js", "utf8"), {
1056 To replace an identifier with an arbitrary non-constant expression it is
1057 necessary to prefix the `global_defs` key with `"@"` to instruct UglifyJS
1058 to parse the value as an expression:
1060 UglifyJS.minify("alert('hello');", {
1063 "@alert": "console.log"
1067 // returns: 'console.log("hello");'
1070 Otherwise it would be replaced as string literal:
1072 UglifyJS.minify("alert('hello');", {
1075 "alert": "console.log"
1079 // returns: '"console.log"("hello");'
1082 ### Using native Uglify AST with `minify()`
1084 // example: parse only, produce native Uglify AST
1086 var result = UglifyJS.minify(code, {
1092 code: false // optional - faster if false
1096 // result.ast contains native Uglify AST
1099 // example: accept native Uglify AST input and then compress and mangle
1100 // to produce both code and native AST.
1102 var result = UglifyJS.minify(ast, {
1107 code: true // optional - faster if false
1111 // result.ast contains native Uglify AST
1112 // result.code contains the minified code in string form.
1115 ### Working with Uglify AST
1117 Transversal and transformation of the native AST can be performed through
1118 [`TreeWalker`](https://github.com/mishoo/UglifyJS/blob/master/lib/ast.js) and
1119 [`TreeTransformer`](https://github.com/mishoo/UglifyJS/blob/master/lib/transform.js)
1122 ### ESTree / SpiderMonkey AST
1124 UglifyJS has its own abstract syntax tree format; for
1125 [practical reasons](http://lisperator.net/blog/uglifyjs-why-not-switching-to-spidermonkey-ast/)
1126 we can't easily change to using the SpiderMonkey AST internally. However,
1127 UglifyJS now has a converter which can import a SpiderMonkey AST.
1129 For example [Acorn][acorn] is a super-fast parser that produces a
1130 SpiderMonkey AST. It has a small CLI utility that parses one file and dumps
1131 the AST in JSON on the standard output. To use UglifyJS to mangle and
1134 acorn file.js | uglifyjs -p spidermonkey -m -c
1136 The `-p spidermonkey` option tells UglifyJS that all input files are not
1137 JavaScript, but JS code described in SpiderMonkey AST in JSON. Therefore we
1138 don't use our own parser in this case, but just transform that AST into our
1141 ### Use Acorn for parsing
1143 More for fun, I added the `-p acorn` option which will use Acorn to do all
1144 the parsing. If you pass this option, UglifyJS will `require("acorn")`.
1146 Acorn is really fast (e.g. 250ms instead of 380ms on some 650K code), but
1147 converting the SpiderMonkey tree that Acorn produces takes another 150ms so
1148 in total it's a bit more than just using UglifyJS's own parser.
1150 [acorn]: https://github.com/ternjs/acorn
1151 [sm-spec]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k
1153 ### Uglify Fast Minify Mode
1155 It's not well known, but whitespace removal and symbol mangling accounts
1156 for 95% of the size reduction in minified code for most JavaScript - not
1157 elaborate code transforms. One can simply disable `compress` to speed up
1158 Uglify builds by 3 to 5 times.
1160 | d3.js | minify size | gzip size | minify time (seconds) |
1161 | --- | ---: | ---: | ---: |
1162 | original | 511,371 | 119,932 | - |
1163 | uglify-js@3.13.0 mangle=false, compress=false | 363,988 | 95,695 | 0.56 |
1164 | uglify-js@3.13.0 mangle=true, compress=false | 253,305 | 81,281 | 0.99 |
1165 | uglify-js@3.13.0 mangle=true, compress=true | 244,436 | 79,854 | 5.30 |
1167 To enable fast minify mode from the CLI use:
1171 To enable fast minify mode with the API use:
1173 UglifyJS.minify(code, { compress: false, mangle: true });
1176 ### Source maps and debugging
1178 Various `compress` transforms that simplify, rearrange, inline and remove code
1179 are known to have an adverse effect on debugging with source maps. This is
1180 expected as code is optimized and mappings are often simply not possible as
1181 some code no longer exists. For highest fidelity in source map debugging
1182 disable the Uglify `compress` option and just use `mangle`.
1184 ### Compiler assumptions
1186 To allow for better optimizations, the compiler makes various assumptions:
1188 - The code does not rely on preserving its runtime performance characteristics.
1189 Typically uglified code will run faster due to less instructions and easier
1190 inlining, but may be slower on rare occasions for a specific platform, e.g.
1191 see [`reduce_funcs`](#compress-options).
1192 - `.toString()` and `.valueOf()` don't have side effects, and for built-in
1193 objects they have not been overridden.
1194 - `undefined`, `NaN` and `Infinity` have not been externally redefined.
1195 - `arguments.callee`, `arguments.caller` and `Function.prototype.caller` are not used.
1196 - The code doesn't expect the contents of `Function.prototype.toString()` or
1197 `Error.prototype.stack` to be anything in particular.
1198 - Getting and setting properties on a plain object does not cause other side effects
1199 (using `.watch()` or `Proxy`).
1200 - Object properties can be added, removed and modified (not prevented with
1201 `Object.defineProperty()`, `Object.defineProperties()`, `Object.freeze()`,
1202 `Object.preventExtensions()` or `Object.seal()`).
1203 - If array destructuring is present, index-like properties in `Array.prototype`
1204 have not been overridden:
1206 Object.prototype[0] = 42;
1210 console.log([][0], a);
1212 console.log({}[0], b);
1214 - Earlier versions of JavaScript will throw `SyntaxError` with the following:
1220 // SyntaxError: Object literal may not have data and accessor property with
1223 UglifyJS may modify the input which in turn may suppress those errors.
1224 - Iteration order of keys over an object which contains spread syntax in later
1225 versions of Chrome and Node.js may be altered.
1226 - When `toplevel` is enabled, UglifyJS effectively assumes input code is wrapped
1227 within `function(){ ... }`, thus forbids aliasing of declared global variables:
1231 // can be `global`, `self`, `window` etc.
1232 var top = function() {
1238 // "FAIL" after compress and/or mangle
1242 - Use of `arguments` alongside destructuring as function parameters, e.g.
1243 `function({}, arguments) {}` will result in `SyntaxError` in earlier versions
1244 of Chrome and Node.js - UglifyJS may modify the input which in turn may
1245 suppress those errors.
1246 - Earlier versions of Chrome and Node.js will throw `ReferenceError` with the
1254 // ReferenceError: a is not defined
1259 UglifyJS may modify the input which in turn may suppress those errors.
1260 - Later versions of JavaScript will throw `SyntaxError` with the following:
1265 // SyntaxError: Identifier 'a' has already been declared
1267 UglifyJS may modify the input which in turn may suppress those errors.
1268 - Later versions of JavaScript will throw `SyntaxError` with the following:
1272 } catch ({ message: a }) {
1275 // SyntaxError: Identifier 'a' has already been declared
1277 UglifyJS may modify the input which in turn may suppress those errors.
1278 - Some versions of Chrome and Node.js will throw `ReferenceError` with the
1281 console.log(((a, b = function() {
1283 // ReferenceError: a is not defined
1286 UglifyJS may modify the input which in turn may suppress those errors.
1287 - Some arithmetic operations with `BigInt` may throw `TypeError`:
1290 // TypeError: can't convert BigInt to number
1292 UglifyJS may modify the input which in turn may suppress those errors.
1293 - Some versions of JavaScript will throw `SyntaxError` with the
1296 console.log(String.raw`\uFo`);
1297 // SyntaxError: Invalid Unicode escape sequence
1299 UglifyJS may modify the input which in turn may suppress those errors.
1300 - Some versions of JavaScript will throw `SyntaxError` with the
1306 // SyntaxError: Identifier 'e' has already been declared
1308 UglifyJS may modify the input which in turn may suppress those errors.
1309 - Some versions of Chrome and Node.js will give incorrect results with the
1318 // Expected: { '42': 'PASS' }
1319 // Actual: { '42': undefined }
1321 UglifyJS may modify the input which in turn may suppress those errors.
1322 - Later versions of JavaScript will throw `SyntaxError` with the following:
1325 async function f() {
1330 // SyntaxError: Unexpected reserved word
1332 UglifyJS may modify the input which in turn may suppress those errors.
1333 - Later versions of JavaScript will throw `SyntaxError` with the following:
1337 // SyntaxError: The left-hand side of a for-of loop may not be 'async'.
1339 UglifyJS may modify the input which in turn may suppress those errors.
1340 - Later versions of Chrome and Node.js will give incorrect results with the
1353 UglifyJS may modify the input which in turn may suppress those errors.
1354 - Earlier versions of JavaScript will throw `TypeError` with the following:
1364 // TypeError: const 'a' has already been declared
1366 UglifyJS may modify the input which in turn may suppress those errors.