html-minifier-next 4.7.1 → 4.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -159,7 +159,7 @@ Options can be used in config files (camelCase) or via CLI flags (kebab-case wit
159
159
  | `minifyURLs`<br>`--minify-urls` | Minify URLs in various attributes (uses [relateurl](https://github.com/stevenvachon/relateurl)) | `false` (could be `String`, `Object`, `Function(text)`, `async Function(text)`) |
160
160
  | `noNewlinesBeforeTagClose`<br>`--no-newlines-before-tag-close` | Never add a newline before a tag that closes an element | `false` |
161
161
  | `partialMarkup`<br>`--partial-markup` | Treat input as a partial HTML fragment, preserving stray end tags (closing tags without opening tags) and preventing auto-closing of unclosed tags at end of input | `false` |
162
- | `preserveLineBreaks`<br>`--preserve-line-breaks` | Always collapse to 1 line break (never remove it entirely) when whitespace between tags includes a line break—use with `collapseWhitespace: true` | `false` |
162
+ | `preserveLineBreaks`<br>`--preserve-line-breaks` | Always collapse to one line break (never remove it entirely) when whitespace between tags includes a line break—use with `collapseWhitespace: true` | `false` |
163
163
  | `preventAttributesEscaping`<br>`--prevent-attributes-escaping` | Prevents the escaping of the values of attributes | `false` |
164
164
  | `processConditionalComments`<br>`--process-conditional-comments` | Process contents of conditional comments through minifier | `false` |
165
165
  | `processScripts`<br>`--process-scripts` | Array of strings corresponding to types of `script` elements to process through minifier (e.g., `text/ng-template`, `text/x-handlebars-template`, etc.) | `[]` |
@@ -168,6 +168,7 @@ Options can be used in config files (camelCase) or via CLI flags (kebab-case wit
168
168
  | `removeComments`<br>`--remove-comments` | [Strip HTML comments](https://perfectionkills.com/experimenting-with-html-minifier#remove_comments) | `false` |
169
169
  | `removeEmptyAttributes`<br>`--remove-empty-attributes` | [Remove all attributes with whitespace-only values](https://perfectionkills.com/experimenting-with-html-minifier#remove_empty_or_blank_attributes) | `false` (could be `true`, `Function(attrName, tag)`) |
170
170
  | `removeEmptyElements`<br>`--remove-empty-elements` | [Remove all elements with empty contents](https://perfectionkills.com/experimenting-with-html-minifier#remove_empty_elements) | `false` |
171
+ | `removeEmptyElementsExcept`<br>`--remove-empty-elements-except` | Array of elements to preserve when `removeEmptyElements` is enabled; accepts simple tag names (e.g., `["td"]`) or HTML-like markup with attributes (e.g., `["<span aria-hidden='true'>"]`); supports double quotes, single quotes, and unquoted attribute values | `[]` |
171
172
  | `removeOptionalTags`<br>`--remove-optional-tags` | [Remove optional tags](https://perfectionkills.com/experimenting-with-html-minifier#remove_optional_tags) | `false` |
172
173
  | `removeRedundantAttributes`<br>`--remove-redundant-attributes` | [Remove attributes when value matches default](https://meiert.com/blog/optional-html/#toc-attribute-values) | `false` |
173
174
  | `removeScriptTypeAttributes`<br>`--remove-script-type-attributes` | Remove `type="text/javascript"` from `script` elements; other `type` attribute values are left intact | `false` |
@@ -226,33 +227,32 @@ const result = await minify(html, {
226
227
  How does HTML Minifier Next compare to other minifiers? (All with the most aggressive settings, though without [hyper-optimization](https://meiert.com/blog/the-ways-of-writing-html/#toc-hyper-optimized). Minimize does not minify CSS or JS.)
227
228
 
228
229
  <!-- Auto-generated benchmarks, don’t edit -->
229
- | Site | Original Size (KB) | [HTML Minifier Next](https://github.com/j9t/html-minifier-next)<br>![npm last update](https://img.shields.io/npm/last-update/html-minifier-next) | [HTML Minifier Terser](https://github.com/terser/html-minifier-terser)<br>![npm last update](https://img.shields.io/npm/last-update/html-minifier-terser) | [htmlnano](https://github.com/posthtml/htmlnano)<br>![npm last update](https://img.shields.io/npm/last-update/htmlnano) | [@swc/html](https://github.com/swc-project/swc)<br>![npm last update](https://img.shields.io/npm/last-update/@swc/html) | [minify-html](https://github.com/wilsonzlin/minify-html)<br>![npm last update](https://img.shields.io/npm/last-update/@minify-html/node) | [minimize](https://github.com/Swaagie/minimize)<br>![npm last update](https://img.shields.io/npm/last-update/minimize) | [html­com­pressor.­com](https://htmlcompressor.com/) |
230
+ | Site | Original Size (KB) | [HTML Minifier Next](https://github.com/j9t/html-minifier-next)<br>[![npm last update](https://img.shields.io/npm/last-update/html-minifier-next)](https://socket.dev/npm/package/html-minifier-next) | [HTML Minifier Terser](https://github.com/terser/html-minifier-terser)<br>[![npm last update](https://img.shields.io/npm/last-update/html-minifier-terser)](https://socket.dev/npm/package/html-minifier-terser) | [htmlnano](https://github.com/posthtml/htmlnano)<br>[![npm last update](https://img.shields.io/npm/last-update/htmlnano)](https://socket.dev/npm/package/htmlnano) | [@swc/html](https://github.com/swc-project/swc)<br>[![npm last update](https://img.shields.io/npm/last-update/@swc/html)](https://socket.dev/npm/package/@swc/html) | [minify-html](https://github.com/wilsonzlin/minify-html)<br>[![npm last update](https://img.shields.io/npm/last-update/@minify-html/node)](https://socket.dev/npm/package/@minify-html/node) | [minimize](https://github.com/Swaagie/minimize)<br>[![npm last update](https://img.shields.io/npm/last-update/minimize)](https://socket.dev/npm/package/minimize) | [html­com­pressor.­com](https://htmlcompressor.com/) |
230
231
  | --- | --- | --- | --- | --- | --- | --- | --- | --- |
231
232
  | [A List Apart](https://alistapart.com/) | 59 | **49** | 50 | 51 | 52 | 51 | 54 | 52 |
232
- | [Apple](https://www.apple.com/) | 181 | **140** | **140** | 159 | 162 | 163 | 167 | 165 |
233
- | [BBC](https://www.bbc.co.uk/) | 728 | **662** | 672 | 684 | 684 | 685 | 721 | n/a |
234
- | [CSS-Tricks](https://css-tricks.com/) | 161 | 121 | **119** | 127 | 142 | 142 | 147 | 144 |
235
- | [ECMAScript](https://tc39.es/ecma262/) | 7237 | **6341** | **6341** | 6561 | 6444 | 6567 | 6614 | n/a |
236
- | [EFF](https://www.eff.org/) | 55 | **47** | **47** | 49 | 48 | 49 | 50 | 50 |
237
- | [FAZ](https://www.faz.net/aktuell/) | 1487 | 1386 | 1391 | **1338** | 1416 | 1426 | 1437 | n/a |
238
- | [Frontend Dogma](https://frontenddogma.com/) | 221 | **212** | **212** | 233 | 218 | 220 | 238 | 219 |
239
- | [Google](https://www.google.com/) | 18 | **17** | **17** | **17** | **17** | **17** | 18 | 18 |
240
- | [Ground News](https://ground.news/) | 2345 | **2060** | 2063 | 2155 | 2176 | 2181 | 2332 | n/a |
233
+ | [Apple](https://www.apple.com/) | 258 | **202** | **202** | 230 | 233 | 234 | 236 | 237 |
234
+ | [BBC](https://www.bbc.co.uk/) | 633 | **575** | 585 | 594 | 594 | 595 | 628 | n/a |
235
+ | [CSS-Tricks](https://css-tricks.com/) | 161 | 121 | **119** | 126 | 141 | 141 | 147 | 143 |
236
+ | [ECMAScript](https://tc39.es/ecma262/) | 7238 | **6341** | **6341** | 6561 | 6444 | 6567 | 6614 | n/a |
237
+ | [EFF](https://www.eff.org/) | 55 | **47** | **47** | 50 | 48 | 49 | 50 | 50 |
238
+ | [FAZ](https://www.faz.net/aktuell/) | 1573 | 1465 | 1470 | **1411** | 1498 | 1509 | 1520 | n/a |
239
+ | [Frontend Dogma](https://frontenddogma.com/) | 222 | **213** | **213** | 234 | 219 | 221 | 239 | 220 |
240
+ | [Google](https://www.google.com/) | 76 | **71** | 72 | n/a | 72 | 73 | 76 | 75 |
241
241
  | [HTML Living Standard](https://html.spec.whatwg.org/multipage/) | 149 | **147** | **147** | 153 | **147** | 149 | 155 | 149 |
242
242
  | [Igalia](https://www.igalia.com/) | 49 | **33** | **33** | 35 | 35 | 35 | 36 | 36 |
243
- | [Leanpub](https://leanpub.com/) | 1405 | **1185** | **1185** | 1192 | 1190 | 1187 | 1399 | n/a |
243
+ | [Leanpub](https://leanpub.com/) | 1457 | **1225** | **1225** | 1232 | 1231 | 1226 | 1451 | n/a |
244
244
  | [Mastodon](https://mastodon.social/explore) | 35 | **26** | **26** | 30 | 33 | 33 | 34 | 34 |
245
245
  | [MDN](https://developer.mozilla.org/en-US/) | 107 | **62** | **62** | 64 | 64 | 65 | 67 | 68 |
246
246
  | [Middle East Eye](https://www.middleeasteye.net/) | 222 | **195** | **195** | 202 | 200 | 200 | 202 | 203 |
247
247
  | [Nielsen Norman Group](https://www.nngroup.com/) | 84 | 71 | 71 | **53** | 71 | 72 | 74 | 73 |
248
- | [SitePoint](https://www.sitepoint.com/) | 508 | **366** | **366** | 444 | 482 | 486 | 504 | n/a |
249
- | [TetraLogical](https://tetralogical.com/) | 44 | 38 | 38 | **35** | 38 | 38 | 39 | 39 |
248
+ | [SitePoint](https://www.sitepoint.com/) | 495 | **353** | **353** | 431 | 469 | 473 | 491 | n/a |
249
+ | [TetraLogical](https://tetralogical.com/) | 44 | 38 | 38 | **35** | 37 | 38 | 39 | 39 |
250
250
  | [TPGi](https://www.tpgi.com/) | 99 | **79** | **79** | 84 | 84 | 84 | 88 | 86 |
251
- | [United Nations](https://www.un.org/en/) | 153 | **114** | 116 | 123 | 127 | 126 | 132 | 125 |
252
- | [W3C](https://www.w3.org/) | 50 | **36** | **36** | 38 | 38 | 38 | 40 | 38 |
253
- | **Average processing time** | | 336 ms (22/22) | 374 ms (22/22) | 188 ms (22/22) | 70 ms (22/22) | **17 ms (22/22)** | 366 ms (22/22) | 1351 ms (16/22) |
251
+ | [United Nations](https://www.un.org/en/) | 154 | **115** | 116 | 123 | 127 | 127 | 133 | 126 |
252
+ | [W3C](https://www.w3.org/) | 50 | **36** | **36** | 38 | 38 | 38 | 40 | 39 |
253
+ | **Average processing time** | | 352 ms (21/21) | 401 ms (21/21) | 175 ms (20/21) | 56 ms (21/21) | **17 ms (21/21)** | 395 ms (21/21) | 1481 ms (16/21) |
254
254
 
255
- (Last updated: Dec 7, 2025)
255
+ (Last updated: Dec 10, 2025)
256
256
  <!-- End auto-generated -->
257
257
 
258
258
  ## Examples
@@ -262,7 +262,7 @@ How does HTML Minifier Next compare to other minifiers? (All with the most aggre
262
262
  **Sample command line:**
263
263
 
264
264
  ```bash
265
- html-minifier-next --collapse-whitespace --remove-comments --minify-js true --input-dir=. --output-dir=example
265
+ html-minifier-next --collapse-whitespace --remove-comments --minify-js --input-dir=. --output-dir=example
266
266
  ```
267
267
 
268
268
  **Process specific files and directories:**
package/cli.js CHANGED
@@ -119,9 +119,9 @@ const mainOptions = {
119
119
  caseSensitive: 'Treat attributes in case-sensitive manner (useful for custom HTML elements)',
120
120
  collapseBooleanAttributes: 'Omit attribute values from boolean attributes',
121
121
  customFragmentQuantifierLimit: ['Set maximum quantifier limit for custom fragments to prevent ReDoS attacks (default: 200)', parseValidInt('customFragmentQuantifierLimit')],
122
- collapseInlineTagWhitespace: 'Don’t leave any spaces between “display: inline;” elements when collapsing—use with “collapseWhitespace=true”',
122
+ collapseInlineTagWhitespace: 'Don’t leave any spaces between “display: inline;” elements when collapsing—use with “--collapse-whitespace”',
123
123
  collapseWhitespace: 'Collapse whitespace that contributes to text nodes in a document tree',
124
- conservativeCollapse: 'Always collapse to 1 space (never remove it entirely)—use with “collapseWhitespace=true”',
124
+ conservativeCollapse: 'Always collapse to 1 space (never remove it entirely)—use with “--collapse-whitespace”',
125
125
  continueOnMinifyError: 'Abort on minification errors',
126
126
  continueOnParseError: 'Handle parse errors instead of aborting',
127
127
  customAttrAssign: ['Arrays of regexes that allow to support custom attribute assign expressions (e.g., “<div flex?="{{mode != cover}}"></div>”)', parseJSONRegExpArray],
@@ -142,7 +142,7 @@ const mainOptions = {
142
142
  minifyURLs: ['Minify URLs in various attributes (uses relateurl)', parseJSON],
143
143
  noNewlinesBeforeTagClose: 'Never add a newline before a tag that closes an element',
144
144
  partialMarkup: 'Treat input as a partial HTML fragment, preserving stray end tags and unclosed tags',
145
- preserveLineBreaks: 'Always collapse to 1 line break (never remove it entirely) when whitespace between tags includes a line break—use with "collapseWhitespace=true"',
145
+ preserveLineBreaks: 'Always collapse to one line break (never remove it entirely) when whitespace between tags includes a line break—use with “--collapse-whitespace”',
146
146
  preventAttributesEscaping: 'Prevents the escaping of the values of attributes',
147
147
  processConditionalComments: 'Process contents of conditional comments through minifier',
148
148
  processScripts: ['Array of strings corresponding to types of “script” elements to process through minifier (e.g., “text/ng-template”, “text/x-handlebars-template”, etc.)', parseJSONArray],
@@ -151,6 +151,7 @@ const mainOptions = {
151
151
  removeComments: 'Strip HTML comments',
152
152
  removeEmptyAttributes: 'Remove all attributes with whitespace-only values',
153
153
  removeEmptyElements: 'Remove all elements with empty contents',
154
+ removeEmptyElementsExcept: ['Array of elements to preserve when “--remove-empty-elements” is enabled (e.g., “td”, “["td", "<span aria-hidden=\'true\'>"]”)', parseJSONArray],
154
155
  removeOptionalTags: 'Remove unrequired tags',
155
156
  removeRedundantAttributes: 'Remove attributes when value matches default',
156
157
  removeScriptTypeAttributes: 'Remove “type="text/javascript"” from “script” elements; other “type” attribute values are left intact',