html-minifier-next 4.18.0 → 4.19.1
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/LICENSE +0 -2
- package/README.md +81 -22
- package/cli.js +2 -2
- package/dist/htmlminifier.cjs +186 -85
- package/dist/htmlminifier.esm.bundle.js +400 -120
- package/dist/types/htmlminifier.d.ts +20 -0
- package/dist/types/htmlminifier.d.ts.map +1 -1
- package/dist/types/htmlparser.d.ts.map +1 -1
- package/dist/types/lib/options.d.ts +1 -2
- package/dist/types/lib/options.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/htmlminifier.js +68 -7
- package/src/htmlparser.js +111 -63
- package/src/lib/options.js +8 -14
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/html-minifier-next) [](https://github.com/j9t/html-minifier-next/actions) [](https://socket.dev/npm/package/html-minifier-next)
|
|
4
4
|
|
|
5
|
-
HTML Minifier Next (HMN) is a **super-configurable, well-tested, JavaScript-based HTML minifier**
|
|
5
|
+
Your HTML precision tool: HTML Minifier Next (HMN) is a **super-configurable, well-tested, JavaScript-based HTML minifier** able to also handle in-document CSS, JavaScript, and SVG minification.
|
|
6
6
|
|
|
7
7
|
The project was based on [HTML Minifier Terser (HMT)](https://github.com/terser/html-minifier-terser), which in turn had been based on [Juriy “kangax” Zaytsev’s HTML Minifier (HM)](https://github.com/kangax/html-minifier); as of 2025, both HTML Minifier Terser and HTML Minifier had been unmaintained for several years. HMN offers additional features and has been optimized for speed. While an independent project, it is still backwards-compatible with HMT and HM.
|
|
8
8
|
|
|
@@ -87,10 +87,10 @@ console.log(result); // “<p title=example id=moo>foo”
|
|
|
87
87
|
CommonJS:
|
|
88
88
|
|
|
89
89
|
```javascript
|
|
90
|
-
const { minify
|
|
90
|
+
const { minify } = require('html-minifier-next');
|
|
91
91
|
|
|
92
92
|
(async () => {
|
|
93
|
-
const result = await minify('<p title="example" id="moo">foo</p>',
|
|
93
|
+
const result = await minify('<p title="example" id="moo">foo</p>', { preset: 'comprehensive' });
|
|
94
94
|
console.log(result); // “<p id=moo title=example>foo”
|
|
95
95
|
})();
|
|
96
96
|
```
|
|
@@ -101,8 +101,8 @@ See [the original blog post](https://perfectionkills.com/experimenting-with-html
|
|
|
101
101
|
|
|
102
102
|
HTML Minifier Next provides presets for common use cases. Presets are pre-configured option sets that can be used as a starting point:
|
|
103
103
|
|
|
104
|
-
* `conservative`:
|
|
105
|
-
* `comprehensive`: More
|
|
104
|
+
* `conservative`: Basic minification with whitespace collapsing, comment removal, and removal of select attributes.
|
|
105
|
+
* `comprehensive`: More advanced minification for better file size reduction, including relevant conservative options plus attribute quote removal, optional tag removal, and more.
|
|
106
106
|
|
|
107
107
|
To review the specific options set, [presets.js](https://github.com/j9t/html-minifier-next/blob/main/src/presets.js) lists them in an accessible manner.
|
|
108
108
|
|
|
@@ -130,6 +130,8 @@ Options can be used in config files (camelCase) or via CLI flags (kebab-case wit
|
|
|
130
130
|
|
|
131
131
|
| Option (config/CLI) | Description | Default |
|
|
132
132
|
| --- | --- | --- |
|
|
133
|
+
| `cacheCSS`<br>`--cache-css` | Set CSS minification cache size; higher values improve performance for batch processing | `500` |
|
|
134
|
+
| `cacheJS`<br>`--cache-js` | Set JavaScript minification cache size; higher values improve performance for batch processing | `500` |
|
|
133
135
|
| `caseSensitive`<br>`--case-sensitive` | Treat attributes in case-sensitive manner (useful for custom HTML elements) | `false` |
|
|
134
136
|
| `collapseAttributeWhitespace`<br>`--collapse-attribute-whitespace` | Trim and collapse whitespace characters within attribute values | `false` |
|
|
135
137
|
| `collapseBooleanAttributes`<br>`--collapse-boolean-attributes` | [Omit attribute values from boolean attributes](https://perfectionkills.com/experimenting-with-html-minifier/#collapse_boolean_attributes) | `false` |
|
|
@@ -181,7 +183,7 @@ Options can be used in config files (camelCase) or via CLI flags (kebab-case wit
|
|
|
181
183
|
|
|
182
184
|
### Sorting attributes and style classes
|
|
183
185
|
|
|
184
|
-
Minifier options like `sortAttributes` and `sortClassName` won’t impact the plain‑text size of the output. However, using these options for more consistent ordering improves the compression ratio for
|
|
186
|
+
Minifier options like `sortAttributes` and `sortClassName` won’t impact the plain‑text size of the output. However, using these options for more consistent ordering improves the compression ratio for Gzip and Brotli used over HTTP.
|
|
185
187
|
|
|
186
188
|
### CSS minification
|
|
187
189
|
|
|
@@ -284,6 +286,59 @@ const result = await minify(html, {
|
|
|
284
286
|
});
|
|
285
287
|
```
|
|
286
288
|
|
|
289
|
+
### CSS and JavaScript cache configuration
|
|
290
|
+
|
|
291
|
+
HTML Minifier Next uses in-memory caches to improve performance when processing multiple files or repeated content. The cache sizes can be configured for optimal performance based on your use case:
|
|
292
|
+
|
|
293
|
+
```javascript
|
|
294
|
+
const result = await minify(html, {
|
|
295
|
+
minifyCSS: true,
|
|
296
|
+
minifyJS: true,
|
|
297
|
+
// Configure cache sizes (in number of entries)
|
|
298
|
+
cacheCSS: 750, // CSS cache size, default: 500
|
|
299
|
+
cacheJS: 250 // JS cache size, default: 500
|
|
300
|
+
});
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
**Via CLI flags:**
|
|
304
|
+
|
|
305
|
+
```shell
|
|
306
|
+
html-minifier-next --minify-css --cache-css 750 --minify-js --cache-js 250 input.html
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
**Via environment variables:**
|
|
310
|
+
|
|
311
|
+
```shell
|
|
312
|
+
export HMN_CACHE_CSS=750
|
|
313
|
+
export HMN_CACHE_JS=250
|
|
314
|
+
html-minifier-next --minify-css --minify-js input.html
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
**Configuration file:**
|
|
318
|
+
|
|
319
|
+
```json
|
|
320
|
+
{
|
|
321
|
+
"minifyCSS": true,
|
|
322
|
+
"cacheCSS": 750,
|
|
323
|
+
"minifyJS": true,
|
|
324
|
+
"cacheJS": 250
|
|
325
|
+
}
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
**When to adjust cache sizes:**
|
|
329
|
+
|
|
330
|
+
* Single file processing: Default `500` is sufficient
|
|
331
|
+
* Batch processing: Increase to `1000` or higher for better cache hit rates
|
|
332
|
+
* Memory-constrained environments: Reduce to `200`–`300` to save memory
|
|
333
|
+
* Hundreds/thousands of files: Increase to `1000`–`2000` for optimal performance
|
|
334
|
+
|
|
335
|
+
**Important:**
|
|
336
|
+
|
|
337
|
+
* Cache locking: Caches are created on the first `minify()` call and persist for the process lifetime. Cache sizes are locked after first initialization—subsequent calls reuse the same caches even if different `cacheCSS`/`cacheJS` options are provided. The first call’s options determine the cache sizes.
|
|
338
|
+
* Zero values: Explicit `0` values are coerced to `1` (minimum functional cache size) to avoid immediate eviction. If you want to minimize memory usage, use a small number like `10` or `50` instead of `0`.
|
|
339
|
+
|
|
340
|
+
The caches persist across multiple `minify()` calls, making them particularly effective when processing many files in a batch operation.
|
|
341
|
+
|
|
287
342
|
### SVG minification
|
|
288
343
|
|
|
289
344
|
When `minifySVG` is set to `true`, HTML Minifier Next applies SVG-specific optimizations to SVG elements and their attributes. These optimizations are lightweight, fast, and safe:
|
|
@@ -312,6 +367,10 @@ What gets optimized:
|
|
|
312
367
|
- `fill-opacity="1"` → removed
|
|
313
368
|
- `stroke-linecap="butt"` → removed
|
|
314
369
|
|
|
370
|
+
5. Leading and trailing zero removal: Unnecessary zeros are stripped from numeric values
|
|
371
|
+
- `0.5` → `.5`, `-0.3` → `-.3` (leading zeros)
|
|
372
|
+
- `1.0` → `1`, `10.500` → `10.5` (trailing zeros)
|
|
373
|
+
|
|
315
374
|
You can customize the optimization behavior by providing an options object:
|
|
316
375
|
|
|
317
376
|
```javascript
|
|
@@ -345,38 +404,38 @@ How does HTML Minifier Next compare to other minifiers? (All minification with t
|
|
|
345
404
|
| Site | Original Size (KB) | [HTML Minifier Next](https://github.com/j9t/html-minifier-next) ([config](https://github.com/j9t/html-minifier-next/blob/main/benchmarks/html-minifier.json))<br>[](https://socket.dev/npm/package/html-minifier-next) | [htmlnano](https://github.com/posthtml/htmlnano)<br>[](https://socket.dev/npm/package/htmlnano) | [@swc/html](https://github.com/swc-project/swc)<br>[](https://socket.dev/npm/package/@swc/html) | [minify-html](https://github.com/wilsonzlin/minify-html)<br>[](https://socket.dev/npm/package/@minify-html/node) | [minimize](https://github.com/Swaagie/minimize)<br>[](https://socket.dev/npm/package/minimize) | [htmlcompressor.com](https://htmlcompressor.com/) |
|
|
346
405
|
| --- | --- | --- | --- | --- | --- | --- | --- |
|
|
347
406
|
| [A List Apart](https://alistapart.com/) | 59 | **49** | 51 | 52 | 51 | 54 | 52 |
|
|
348
|
-
| [Apple](https://www.apple.com/) |
|
|
349
|
-
| [BBC](https://www.bbc.co.uk/) |
|
|
407
|
+
| [Apple](https://www.apple.com/) | 255 | **197** | 226 | 230 | 231 | 233 | 233 |
|
|
408
|
+
| [BBC](https://www.bbc.co.uk/) | 620 | **562** | 582 | 583 | 584 | 615 | n/a |
|
|
350
409
|
| [CERN](https://home.cern/) | 151 | **82** | 90 | 90 | 91 | 93 | 95 |
|
|
351
|
-
| [CSS-Tricks](https://css-tricks.com/) | 161 | **119** | 126 |
|
|
410
|
+
| [CSS-Tricks](https://css-tricks.com/) | 161 | **119** | 126 | 142 | 142 | 147 | 143 |
|
|
352
411
|
| [ECMAScript](https://tc39.es/ecma262/) | 7250 | **6401** | 6573 | 6455 | 6578 | 6626 | n/a |
|
|
353
412
|
| [EDRi](https://edri.org/) | 80 | **59** | 70 | 70 | 71 | 75 | 73 |
|
|
354
|
-
| [EFF](https://www.eff.org/) | 54 | **45** |
|
|
413
|
+
| [EFF](https://www.eff.org/) | 54 | **45** | 48 | 47 | 48 | 49 | 49 |
|
|
355
414
|
| [European Alternatives](https://european-alternatives.eu/) | 48 | **30** | 32 | 32 | 32 | 32 | 32 |
|
|
356
|
-
| [FAZ](https://www.faz.net/aktuell/) |
|
|
415
|
+
| [FAZ](https://www.faz.net/aktuell/) | 1596 | 1458 | **1430** | 1520 | 1531 | 1542 | n/a |
|
|
357
416
|
| [French Tech](https://lafrenchtech.gouv.fr/) | 153 | **122** | 126 | 126 | 126 | 132 | 127 |
|
|
358
|
-
| [Frontend Dogma](https://frontenddogma.com/) | 228 | **220** |
|
|
417
|
+
| [Frontend Dogma](https://frontenddogma.com/) | 228 | **220** | 241 | 226 | 228 | 247 | 228 |
|
|
359
418
|
| [Google](https://www.google.com/) | 18 | **16** | 17 | 17 | 17 | 18 | 18 |
|
|
360
|
-
| [Ground News](https://ground.news/) |
|
|
419
|
+
| [Ground News](https://ground.news/) | 1658 | **1431** | 1526 | 1548 | 1553 | 1645 | n/a |
|
|
361
420
|
| [HTML Living Standard](https://html.spec.whatwg.org/multipage/) | 149 | 148 | 153 | **147** | 149 | 155 | 149 |
|
|
362
421
|
| [Igalia](https://www.igalia.com/) | 49 | **33** | 36 | 35 | 36 | 36 | 36 |
|
|
363
|
-
| [Leanpub](https://leanpub.com/) |
|
|
422
|
+
| [Leanpub](https://leanpub.com/) | 233 | **204** | 219 | 219 | 219 | 228 | 230 |
|
|
364
423
|
| [Mastodon](https://mastodon.social/explore) | 38 | **28** | 32 | 35 | 35 | 36 | 36 |
|
|
365
424
|
| [MDN](https://developer.mozilla.org/en-US/) | 109 | **62** | 64 | 65 | 65 | 68 | 68 |
|
|
366
|
-
| [Middle East Eye](https://www.middleeasteye.net/) |
|
|
425
|
+
| [Middle East Eye](https://www.middleeasteye.net/) | 222 | **196** | 202 | 200 | 200 | 201 | 202 |
|
|
367
426
|
| [Mistral AI](https://mistral.ai/) | 364 | **319** | 326 | 329 | 330 | 360 | n/a |
|
|
368
|
-
| [Mozilla](https://www.mozilla.org/) |
|
|
369
|
-
| [Nielsen Norman Group](https://www.nngroup.com/) | 93 | 70 | **57** |
|
|
370
|
-
| [SitePoint](https://www.sitepoint.com/) |
|
|
427
|
+
| [Mozilla](https://www.mozilla.org/) | 45 | **31** | 35 | 34 | 34 | 35 | 35 |
|
|
428
|
+
| [Nielsen Norman Group](https://www.nngroup.com/) | 93 | 70 | **57** | 76 | 77 | 78 | 78 |
|
|
429
|
+
| [SitePoint](https://www.sitepoint.com/) | 522 | **391** | 463 | 496 | 501 | 519 | n/a |
|
|
371
430
|
| [Startup-Verband](https://startupverband.de/) | 43 | **30** | 31 | **30** | 31 | 31 | 31 |
|
|
372
|
-
| [TetraLogical](https://tetralogical.com/) |
|
|
431
|
+
| [TetraLogical](https://tetralogical.com/) | 48 | **22** | 39 | 41 | 42 | 42 | 42 |
|
|
373
432
|
| [TPGi](https://www.tpgi.com/) | 173 | **157** | 159 | 163 | 164 | 170 | 170 |
|
|
374
433
|
| [United Nations](https://www.un.org/en/) | 151 | **112** | 121 | 125 | 125 | 130 | 123 |
|
|
375
434
|
| [Vivaldi](https://vivaldi.com/) | 93 | **74** | n/a | 79 | 81 | 84 | 82 |
|
|
376
|
-
| [W3C](https://www.w3.org/) | 51 | **36** | 39 |
|
|
377
|
-
| **Average processing time** | |
|
|
435
|
+
| [W3C](https://www.w3.org/) | 51 | **36** | 39 | 39 | 39 | 41 | 39 |
|
|
436
|
+
| **Average processing time** | | 95 ms (30/30) | 143 ms (29/30) | 46 ms (30/30) | **14 ms (30/30)** | 274 ms (30/30) | 1297 ms (24/30) |
|
|
378
437
|
|
|
379
|
-
(Last updated: Jan
|
|
438
|
+
(Last updated: Jan 20, 2026)
|
|
380
439
|
<!-- End auto-generated -->
|
|
381
440
|
|
|
382
441
|
Notes: Minimize does not minify CSS and JS. [HTML Minifier Terser](https://github.com/terser/html-minifier-terser) is currently not included due to issues around whitespace collapsing and removal of code using modern CSS features, issues which appeared to distort the data.
|
package/cli.js
CHANGED
|
@@ -6,9 +6,7 @@
|
|
|
6
6
|
* The MIT License (MIT)
|
|
7
7
|
*
|
|
8
8
|
* Copyright 2014–2016 Zoltan Frombach
|
|
9
|
-
*
|
|
10
9
|
* Copyright Juriy “kangax” Zaytsev
|
|
11
|
-
*
|
|
12
10
|
* Copyright 2025 Jens Oliver Meiert
|
|
13
11
|
*
|
|
14
12
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
@@ -283,6 +281,8 @@ program.option('--input-dir <dir>', 'Specify an input directory');
|
|
|
283
281
|
program.option('--ignore-dir <patterns>', 'Exclude directories—relative to input directory—from processing (comma-separated), e.g., “libs” or “libs,vendor,node_modules”');
|
|
284
282
|
program.option('--output-dir <dir>', 'Specify an output directory');
|
|
285
283
|
program.option('--file-ext <extensions>', 'Specify file extension(s) to process (comma-separated), e.g., “html” or “html,htm,php”');
|
|
284
|
+
program.option('--cache-css <size>', 'Set CSS minification cache size (number of entries, default: 500)', parseValidInt('cacheCSS'));
|
|
285
|
+
program.option('--cache-js <size>', 'Set JavaScript minification cache size (number of entries, default: 500)', parseValidInt('cacheJS'));
|
|
286
286
|
|
|
287
287
|
(async () => {
|
|
288
288
|
let content;
|