# What changed in juice

> 29 changes in juice 11 to 12 from its official release notes, upgrade guides and advisories: 7 breaking, 1 security, 9 new APIs and options. Each one cited. Sources checked 2026-10-18. HTML: https://unstale.sh/npm/juice/

To see which of these apply to a repository, run `npx @unstale/cli init` in it.

## juice 12

### Breaking changes

- Non-string HTML input now produces a clear `TypeError`. (12.2.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v12.2.0)
- Browserify can no longer bundle juice/client because client.js is ESM; use a modern bundler instead. (12.0.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v12.0.0)
- Juice is now ESM-only. Node 22.12+ can still load it through require(esm); older Node versions must upgrade or use an ESM import. (12.0.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v12.0.0)
- TypeScript declarations are now named index.d.ts and restructured for ESM default-export resolution. (12.0.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v12.0.0)
- The minimum supported Node version is now 22.12.0; Node 18 and Node 20 are no longer supported. (12.0.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v12.0.0)
- CSS preserved inside <style> blocks is now canonically formatted, so output may differ from previous formatting. (12.0.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v12.0.0)
- Specificity for :is(), :where(), :has(), and :not() now follows CSS Selectors Level 4; cascade resolution may change for styles relying on the previous behavior. (12.0.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v12.0.0)

### Security

- Prevents ReDoS in CSS variable parsing, reducing the risk of denial-of-service when processing CSS. (12.1.2) — [release notes](https://github.com/Automattic/juice/releases/tag/v12.1.2)

### New APIs and options

- Adds an option to add `!important` to pseudo-classes. (12.2.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v12.2.0)
- FreeMarker templates are supported in `codeBlocks` by default. (12.2.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v12.2.0)
- The CLI supports reading from stdin and writing to stdout. (12.2.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v12.2.0)
- Adds the data-juice-important attribute. (12.1.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v12.1.0)
- TypeScript types are exposed through the types condition in exports and resolve under nodenext module resolution. (12.0.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v12.0.0)
- Adds an option to preserve @container at-rules through inlining; it defaults to true. (12.0.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v12.0.0)
- Adds an option to preserve @layer at-rules through inlining; it defaults to true. (12.0.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v12.0.0)

### Tooling

- The CLI can inline whole directories. (12.2.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v12.2.0)

### Fixes and other changes

- CSS counters are resolved in document order with proper scoping. (12.2.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v12.2.0)
- Element lists are typed as tag name strings. (12.2.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v12.2.0)
- Pseudo-element rules that cannot be inlined are preserved. (12.2.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v12.2.0)
- Style attributes that contain invalid CSS are kept instead of causing an error. (12.2.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v12.2.0)
- Template tags between declarations in style attributes are preserved. (12.2.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v12.2.0)
- Handles `&lt;` and CDATA in style tags when `xmlMode` is enabled. (12.2.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v12.2.0)
- Level 1 nested rules, nested at-rules, parent selectors, and bare nested selectors are flattened before inlining instead of being silently dropped. (12.0.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v12.0.0)
- Long-standing crashes and hangs involving :not(a, b, …) are fixed. (12.0.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v12.0.0)

## juice 11

### New APIs and options

- Adds the preservedSelectors option. (11.1.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v11.1.0)
- Juice can remove inlined selectors. (11.1.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v11.1.0)

### Behavior and default changes

- Juice now ignores comments. (11.1.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v11.1.0)
- Juice can inline duplicate properties. (11.1.0) — [release notes](https://github.com/Automattic/juice/releases/tag/v11.1.0)

### Fixes and other changes

- Fixes handling of style tags with data-embed. (11.1.1) — [release notes](https://github.com/Automattic/juice/releases/tag/v11.1.1)
