html-minifier-next 4.12.2 → 4.14.0
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 +84 -26
- package/cli.js +1 -1
- package/dist/htmlminifier.cjs +1552 -1320
- package/dist/htmlminifier.esm.bundle.js +4204 -3972
- package/dist/types/htmlminifier.d.ts +10 -3
- package/dist/types/htmlminifier.d.ts.map +1 -1
- package/dist/types/htmlparser.d.ts.map +1 -1
- package/dist/types/lib/attributes.d.ts +29 -0
- package/dist/types/lib/attributes.d.ts.map +1 -0
- package/dist/types/lib/constants.d.ts +83 -0
- package/dist/types/lib/constants.d.ts.map +1 -0
- package/dist/types/lib/content.d.ts +7 -0
- package/dist/types/lib/content.d.ts.map +1 -0
- package/dist/types/lib/elements.d.ts +39 -0
- package/dist/types/lib/elements.d.ts.map +1 -0
- package/dist/types/lib/options.d.ts +17 -0
- package/dist/types/lib/options.d.ts.map +1 -0
- package/dist/types/lib/utils.d.ts +21 -0
- package/dist/types/lib/utils.d.ts.map +1 -0
- package/dist/types/lib/whitespace.d.ts +7 -0
- package/dist/types/lib/whitespace.d.ts.map +1 -0
- package/dist/types/presets.d.ts.map +1 -1
- package/package.json +10 -1
- package/src/htmlminifier.js +114 -1229
- package/src/htmlparser.js +11 -11
- package/src/lib/attributes.js +511 -0
- package/src/lib/constants.js +213 -0
- package/src/lib/content.js +105 -0
- package/src/lib/elements.js +242 -0
- package/src/lib/index.js +20 -0
- package/src/lib/options.js +300 -0
- package/src/lib/utils.js +90 -0
- package/src/lib/whitespace.js +139 -0
- package/src/presets.js +0 -1
- package/src/tokenchain.js +1 -1
- package/dist/types/utils.d.ts +0 -2
- package/dist/types/utils.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -161,7 +161,7 @@ Options can be used in config files (camelCase) or via CLI flags (kebab-case wit
|
|
|
161
161
|
| `maxInputLength`<br>`--max-input-length` | Maximum input length to prevent ReDoS attacks (disabled by default) | `undefined` |
|
|
162
162
|
| `maxLineLength`<br>`--max-line-length` | Specify a maximum line length; compressed output will be split by newlines at valid HTML split-points | |
|
|
163
163
|
| `minifyCSS`<br>`--minify-css` | Minify CSS in `style` elements and `style` attributes (uses [Lightning CSS](https://lightningcss.dev/)) | `false` (could be `true`, `Object`, `Function(text, type)`) |
|
|
164
|
-
| `minifyJS`<br>`--minify-js` | Minify JavaScript in `script` elements and event attributes (uses [Terser](https://github.com/terser/terser)) | `false` (could be `true`, `Object`, `Function(text, inline)`) |
|
|
164
|
+
| `minifyJS`<br>`--minify-js` | Minify JavaScript in `script` elements and event attributes (uses [Terser](https://github.com/terser/terser) or [SWC](https://swc.rs/)) | `false` (could be `true`, `Object`, `Function(text, inline)`) |
|
|
165
165
|
| `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)`) |
|
|
166
166
|
| `noNewlinesBeforeTagClose`<br>`--no-newlines-before-tag-close` | Never add a newline before a tag that closes an element | `false` |
|
|
167
167
|
| `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` |
|
|
@@ -189,7 +189,7 @@ Options can be used in config files (camelCase) or via CLI flags (kebab-case wit
|
|
|
189
189
|
|
|
190
190
|
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.
|
|
191
191
|
|
|
192
|
-
### CSS minification
|
|
192
|
+
### CSS minification
|
|
193
193
|
|
|
194
194
|
When `minifyCSS` is set to `true`, HTML Minifier Next uses [Lightning CSS](https://lightningcss.dev/) to minify CSS in `<style>` elements and `style` attributes. Lightning CSS provides excellent minification by default.
|
|
195
195
|
|
|
@@ -228,42 +228,100 @@ const result = await minify(html, {
|
|
|
228
228
|
});
|
|
229
229
|
```
|
|
230
230
|
|
|
231
|
+
### JavaScript minification
|
|
232
|
+
|
|
233
|
+
When `minifyJS` is set to `true`, HTML Minifier Next uses [Terser](https://github.com/terser/terser) by default to minify JavaScript in `<script>` elements and event attributes.
|
|
234
|
+
|
|
235
|
+
You can choose between different JS minifiers using the `engine` field:
|
|
236
|
+
|
|
237
|
+
```js
|
|
238
|
+
const result = await minify(html, {
|
|
239
|
+
minifyJS: {
|
|
240
|
+
engine: 'swc', // Use swc for faster minification
|
|
241
|
+
// SWC-specific options here
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
**Available engines:**
|
|
247
|
+
|
|
248
|
+
* `terser` (default): The standard JavaScript minifier with excellent compression
|
|
249
|
+
* [`swc`](https://swc.rs/): Rust-based minifier that’s significantly faster than Terser (requires separate installation)
|
|
250
|
+
|
|
251
|
+
**To use swc**, install it as a dependency:
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
npm i @swc/core
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**Important:** Inline event handlers (e.g., `onclick="return false"`) always use Terser regardless of the `engine` setting, as SWC doesn’t support bare return statements. This is handled automatically—you don’t need to do anything special.
|
|
258
|
+
|
|
259
|
+
You can pass engine-specific configuration options:
|
|
260
|
+
|
|
261
|
+
```js
|
|
262
|
+
// Using Terser with custom options
|
|
263
|
+
const result = await minify(html, {
|
|
264
|
+
minifyJS: {
|
|
265
|
+
compress: {
|
|
266
|
+
drop_console: true // Remove console.log statements
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
// Using SWC for faster minification
|
|
272
|
+
const result = await minify(html, {
|
|
273
|
+
minifyJS: {
|
|
274
|
+
engine: 'swc'
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
For advanced usage, you can also pass a function:
|
|
280
|
+
|
|
281
|
+
```js
|
|
282
|
+
const result = await minify(html, {
|
|
283
|
+
minifyJS: function(text, inline) {
|
|
284
|
+
// `text`: JavaScript string to minify
|
|
285
|
+
// `inline`: `true` for event handlers (e.g., `onclick`), `false` for `<script>` elements
|
|
286
|
+
return yourCustomMinifier(text);
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
```
|
|
290
|
+
|
|
231
291
|
## Minification comparison
|
|
232
292
|
|
|
233
|
-
How does HTML Minifier Next compare to other minifiers? (All with the most aggressive settings
|
|
293
|
+
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)—and against some large documents.—Minimize does not minify CSS or JS.)
|
|
234
294
|
|
|
235
295
|
<!-- Auto-generated benchmarks, don’t edit -->
|
|
236
|
-
| Site | Original Size (KB) | [HTML Minifier Next](https://github.com/j9t/html-minifier-next)<br>[](https://socket.dev/npm/package/html-minifier-next) | [HTML Minifier Terser](https://github.com/terser/html-minifier-terser)<br>[](https://socket.dev/npm/package/html-minifier-terser) | [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/) |
|
|
296
|
+
| 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) | [HTML Minifier Terser](https://github.com/terser/html-minifier-terser)<br>[](https://socket.dev/npm/package/html-minifier-terser) | [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/) |
|
|
237
297
|
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
238
|
-
| [A List Apart](https://alistapart.com/) | 59 | **
|
|
298
|
+
| [A List Apart](https://alistapart.com/) | 59 | **50** | **50** | 51 | 52 | 51 | 54 | 52 |
|
|
239
299
|
| [Apple](https://www.apple.com/) | 266 | **207** | **207** | 236 | 239 | 240 | 242 | 243 |
|
|
240
|
-
| [BBC](https://www.bbc.co.uk/) |
|
|
241
|
-
| [CERN](https://home.cern/) |
|
|
242
|
-
| [CSS-Tricks](https://css-tricks.com/) |
|
|
243
|
-
| [ECMAScript](https://tc39.es/ecma262/) |
|
|
300
|
+
| [BBC](https://www.bbc.co.uk/) | 701 | **636** | 646 | 658 | 659 | 660 | 695 | n/a |
|
|
301
|
+
| [CERN](https://home.cern/) | 152 | 85 | **84** | 91 | 91 | 91 | 93 | 96 |
|
|
302
|
+
| [CSS-Tricks](https://css-tricks.com/) | 162 | 121 | **120** | 127 | 143 | 143 | 148 | 145 |
|
|
303
|
+
| [ECMAScript](https://tc39.es/ecma262/) | 7250 | **6352** | **6352** | 6573 | 6455 | 6578 | 6626 | n/a |
|
|
244
304
|
| [EDRi](https://edri.org/) | 80 | **59** | 60 | 70 | 70 | 71 | 75 | 73 |
|
|
245
|
-
| [EFF](https://www.eff.org/) | 55 | **
|
|
305
|
+
| [EFF](https://www.eff.org/) | 55 | **45** | 46 | 49 | 48 | 48 | 50 | 50 |
|
|
246
306
|
| [European Alternatives](https://european-alternatives.eu/) | 48 | **30** | **30** | 32 | 32 | 32 | 32 | 32 |
|
|
247
|
-
| [FAZ](https://www.faz.net/aktuell/) |
|
|
248
|
-
| [French Tech](https://lafrenchtech.gouv.fr/) | 152 | **
|
|
249
|
-
| [Frontend Dogma](https://frontenddogma.com/) |
|
|
250
|
-
| [Google](https://www.google.com/) | 18 | **
|
|
251
|
-
| [Ground News](https://ground.news/) |
|
|
307
|
+
| [FAZ](https://www.faz.net/aktuell/) | 1603 | 1494 | 1499 | **1437** | 1526 | 1538 | 1549 | n/a |
|
|
308
|
+
| [French Tech](https://lafrenchtech.gouv.fr/) | 152 | **122** | **122** | 126 | 125 | 125 | 132 | 127 |
|
|
309
|
+
| [Frontend Dogma](https://frontenddogma.com/) | 224 | **214** | 216 | 237 | 222 | 224 | 243 | 223 |
|
|
310
|
+
| [Google](https://www.google.com/) | 18 | **16** | 17 | 17 | 17 | 17 | 18 | 18 |
|
|
311
|
+
| [Ground News](https://ground.news/) | 1713 | **1476** | 1477 | 1577 | 1602 | 1607 | 1699 | n/a |
|
|
252
312
|
| [HTML Living Standard](https://html.spec.whatwg.org/multipage/) | 149 | **147** | **147** | 153 | **147** | 149 | 155 | 149 |
|
|
253
313
|
| [Igalia](https://www.igalia.com/) | 50 | **34** | **34** | 36 | 36 | 36 | 37 | 37 |
|
|
254
|
-
| [
|
|
255
|
-
| [Mastodon](https://mastodon.social/explore) | 37 | **27** | **27** | 32 | 34 | 35 | 35 | 35 |
|
|
314
|
+
| [Mastodon](https://mastodon.social/explore) | 37 | **28** | **28** | 32 | 35 | 35 | 36 | 36 |
|
|
256
315
|
| [MDN](https://developer.mozilla.org/en-US/) | 109 | **62** | **62** | 64 | 65 | 65 | 68 | 68 |
|
|
257
|
-
| [Middle East Eye](https://www.middleeasteye.net/) |
|
|
316
|
+
| [Middle East Eye](https://www.middleeasteye.net/) | 222 | **195** | **195** | 202 | 200 | 200 | 202 | 203 |
|
|
258
317
|
| [Nielsen Norman Group](https://www.nngroup.com/) | 86 | 74 | 74 | **55** | 74 | 75 | 77 | 76 |
|
|
259
|
-
| [SitePoint](https://www.sitepoint.com/) |
|
|
260
|
-
| [TetraLogical](https://tetralogical.com/) | 44 | 38 | 38 | **35** | 38 |
|
|
261
|
-
| [TPGi](https://www.tpgi.com/) | 175 | **
|
|
262
|
-
| [
|
|
263
|
-
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
(Last updated: Dec 17, 2025)
|
|
318
|
+
| [SitePoint](https://www.sitepoint.com/) | 501 | **370** | **370** | 442 | 475 | 480 | 498 | n/a |
|
|
319
|
+
| [TetraLogical](https://tetralogical.com/) | 44 | 38 | 38 | **35** | 38 | 39 | 39 | 39 |
|
|
320
|
+
| [TPGi](https://www.tpgi.com/) | 175 | **159** | 161 | 160 | 164 | 166 | 172 | 172 |
|
|
321
|
+
| [W3C](https://www.w3.org/) | 50 | **36** | **36** | 39 | 38 | 38 | 41 | 39 |
|
|
322
|
+
| **Average processing time** | | 256 ms (24/24) | 352 ms (24/24) | 167 ms (24/24) | 54 ms (24/24) | **15 ms (24/24)** | 339 ms (24/24) | 3288 ms (19/24) |
|
|
323
|
+
|
|
324
|
+
(Last updated: Dec 20, 2025)
|
|
267
325
|
<!-- End auto-generated -->
|
|
268
326
|
|
|
269
327
|
## Examples
|
package/cli.js
CHANGED
|
@@ -141,7 +141,7 @@ const mainOptions = {
|
|
|
141
141
|
maxInputLength: ['Maximum input length to prevent ReDoS attacks', parseValidInt('maxInputLength')],
|
|
142
142
|
maxLineLength: ['Specify a maximum line length; compressed output will be split by newlines at valid HTML split-points', parseValidInt('maxLineLength')],
|
|
143
143
|
minifyCSS: ['Minify CSS in “style” elements and “style” attributes (uses Lightning CSS)', parseJSON],
|
|
144
|
-
minifyJS: ['Minify JavaScript in “script” elements and event attributes (uses Terser)', parseJSON],
|
|
144
|
+
minifyJS: ['Minify JavaScript in “script” elements and event attributes (uses Terser or SWC; pass “{"engine": "swc"}” for SWC)', parseJSON],
|
|
145
145
|
minifyURLs: ['Minify URLs in various attributes (uses relateurl)', parseJSON],
|
|
146
146
|
noNewlinesBeforeTagClose: 'Never add a newline before a tag that closes an element',
|
|
147
147
|
partialMarkup: 'Treat input as a partial HTML fragment, preserving stray end tags and unclosed tags',
|