# What changed in marked

> 85 changes in marked 16 to 18 from its official release notes, upgrade guides and advisories: 5 breaking, 4 security, 4 new APIs and options. Each one cited. Sources checked 2026-10-17. HTML: https://unstale.sh/npm/marked/

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

## marked 18

### Breaking changes

- Unbalanced parentheses in link destinations are now rejected. (18.1.0) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.1.0)
- GFM email autolinks are rejected when their domain ends in an underscore or hyphen. (18.0.12) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.12)
- Trailing blank lines are trimmed from block tokens. (18.0.0) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.0)

### Security

- Fixed an infinite loop when parsing an indented code blank line. (18.0.2) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.2), [security advisory](https://github.com/advisories/GHSA-6V9C-7CG6-27Q7)

### New APIs and options

- Adds lexer state that enables failing fast during link token generation. (18.1.0) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.1.0)

### Performance

- Nested lists avoid repeated raw string copies, improving parsing performance. (18.1.1) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.1.1)
- walkTokens now runs in linear time by appending values in place. (18.1.1) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.1.1)
- Avoids O(n^2) backtracking during HTML block closing and tilde interruption parsing. (18.0.7) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.7)
- Avoids O(n^2) masked source rebuilding during inline tokenization. (18.0.7) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.7)
- Avoids O(n^2) backtracking when processing inline link hrefs. (18.0.6) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.6)

### Fixes and other changes

- Blockquotes now end before a lazy line following a heading, horizontal rule, or HTML block. (18.1.1) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.1.1)
- Decoded character references no longer form a new character reference. (18.1.1) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.1.1)
- The CLI now honors an explicitly empty string input. (18.1.1) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.1.1)
- Backslashes in code spans no longer hide emphasis. (18.1.1) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.1.1)
- Indented and type 3–5 HTML blocks can now interrupt a paragraph. (18.1.1) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.1.1)
- pre, script, style, and textarea are matched as whole tag names. (18.1.1) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.1.1)
- Enclosing link state is preserved after parsing images. (18.1.1) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.1.1)
- List continuation indentation now respects tab stops. (18.1.1) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.1.1)
- CLI configuration files can now be loaded using top-level await. (18.1.0) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.1.0)
- Avoids cubic backtracking on unicode whitespace in link destinations. (18.1.0) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.1.0)
- GFM protocol autolinks are now supported. (18.0.14) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.14)
- Setext heading text now allows indented lines. (18.0.14) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.14)
- Internal tabs in list item content are now preserved. (18.0.14) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.14)
- Whitespace is now stripped when normalizing link reference labels. (18.0.14) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.14)
- Numeric character references are now decoded in text. (18.0.14) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.14)
- Text following an empty nested blockquote is now preserved. (18.0.14) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.14)
- Leading whitespace after a hard line break is now removed. (18.0.13) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.13)
- HTML block start conditions are now matched when ending a list item. (18.0.13) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.13)
- A tab following spaces in an indented code block is now stripped. (18.0.13) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.13)
- Raw tokens are now respected when closing link labels. (18.0.13) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.13)
- Reference link labels are now case-folded during parsing. (18.0.13) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.13)
- Tabs are now allowed in the thematic break that ends a list item. (18.0.13) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.13)
- A tab is now allowed before the closing sequence of an ATX heading. (18.0.12) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.12)
- Character references in autolink destinations are now escaped. (18.0.12) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.12)
- Empty code blocks no longer receive an added newline. (18.0.12) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.12)
- Each content line removes up to the fence indentation. (18.0.12) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.12)
- HTML tags containing invalid characters in their names are now rejected. (18.0.12) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.12)
- Link labels now allow one additional level of nested brackets. (18.0.12) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.12)
- inlineTokens rebuilds the reflink-mask preamble for each call. (18.0.11) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.11)
- Links are no longer nested inside other links during parsing. (18.0.11) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.11)
- Rejected reference links retain emphasis in their text. (18.0.11) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.11)
- The em/strong mask now stays the same length as the source, correcting parsing behavior. (18.0.10) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.10)
- Backtick fences at EOF after paragraphs are now parsed correctly. (18.0.10) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.10)
- Task checkboxes are placed after list looseness is finalized, correcting list parsing. (18.0.10) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.10)
- Blockquote continuation no longer produces spurious deeper nesting during Markdown parsing. (18.0.9) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.9)
- Pedantic emphasis parsing is corrected for foo: and "word" patterns. (18.0.9) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.9)
- An unmatched strong run before emphasis now stays literal during Markdown parsing. (18.0.9) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.9)
- Extensions returning false now fall back to the default checkbox renderer. (18.0.8) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.8)
- Treats a line containing only tabs as a blank line between paragraphs. (18.0.7) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.7)
- Preserves code spans when they appear adjacent to tildes. (18.0.7) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.7)
- Keeps an empty list after a blockquote as a sibling block. (18.0.7) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.7)
- Recognizes setext headings whose first line starts with #. (18.0.7) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.7)
- Preserves trailing text on HTML block close lines for processing instructions, declarations, and CDATA. (18.0.6) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.6)
- Fixes parsing of ordered lists that follow blockquotes. (18.0.6) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.6)
- Parsing now handles empty list items that have a trailing space. (18.0.5) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.5)
- The CLI now correctly reads input from stdin. (18.0.4) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.4)
- Setext heading text no longer incorrectly receives a task checkbox. (18.0.3) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.3)
- Ensures the lookbehind regex is evaluated correctly by minifiers. (18.0.1) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.1)
- GFM table tokens no longer greedily capture trailing newlines. (18.0.0) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.0)
- Heading and definition tokens no longer greedily capture multiple newlines. (18.0.0) — [release notes](https://github.com/markedjs/marked/releases/tag/v18.0.0)

## marked 17

### Breaking changes

- Consecutive text tokens in lists behave differently, which may affect code consuming or producing list tokens. (17.0.0) — [release notes](https://github.com/markedjs/marked/releases/tag/v17.0.0)
- The listItem renderer is simplified, potentially requiring updates to custom renderer implementations. (17.0.0) — [release notes](https://github.com/markedjs/marked/releases/tag/v17.0.0)

### Security

- Catastrophic backtracking (ReDoS) in the link/reflink label regex was fixed. (17.0.5) — [release notes](https://github.com/markedjs/marked/releases/tag/v17.0.5)
- Prevents ReDoS in the inline link regular expression title group. (17.0.4) — [release notes](https://github.com/markedjs/marked/releases/tag/v17.0.4)
- Image alt text is now escaped, preventing unescaped content in rendered output. (17.0.3) — [release notes](https://github.com/markedjs/marked/releases/tag/v17.0.3)

### New APIs and options

- The list tokenizer now adds a checkbox token, exposing checkbox information to token consumers. (17.0.0) — [release notes](https://github.com/markedjs/marked/releases/tag/v17.0.0)
- Checkbox tokens now have a raw property. (17.0.0) — [release notes](https://github.com/markedjs/marked/releases/tag/v17.0.0)
- Checkbox tokens now have a type property. (17.0.0) — [release notes](https://github.com/markedjs/marked/releases/tag/v17.0.0)

### Performance

- Quadratic complexity in the emStrongLDelim regex was prevented. (17.0.5) — [release notes](https://github.com/markedjs/marked/releases/tag/v17.0.5)

### Behavior and default changes

- Loose list text tokens now use paragraph type in the list tokenizer. (17.0.0) — [release notes](https://github.com/markedjs/marked/releases/tag/v17.0.0)

### Fixes and other changes

- The CLI now uses a file URL when importing configuration. (17.0.6) — [release notes](https://github.com/markedjs/marked/releases/tag/v17.0.6)
- Avoided a race condition when using async parallel parse or parseInline with hooks. (17.0.6) — [release notes](https://github.com/markedjs/marked/releases/tag/v17.0.6)
- The CLI now honors a positional input file. (17.0.6) — [release notes](https://github.com/markedjs/marked/releases/tag/v17.0.6)
- Trailing whitespace is trimmed from lheading text. (17.0.5) — [release notes](https://github.com/markedjs/marked/releases/tag/v17.0.5)
- renderer.parser is reassigned at the start of each parse call to ensure fresh parser state. (17.0.5) — [release notes](https://github.com/markedjs/marked/releases/tag/v17.0.5)
- Single-tilde strikethrough false positives were prevented. (17.0.5) — [release notes](https://github.com/markedjs/marked/releases/tag/v17.0.5)
- tokenizer.lexer is reassigned at the start of each parse call to ensure fresh parser state. (17.0.5) — [release notes](https://github.com/markedjs/marked/releases/tag/v17.0.5)
- Fixed blockquote parsing after a list. (17.0.2) — [release notes](https://github.com/markedjs/marked/releases/tag/v17.0.2)
- Fixed parsing of empty list items. (17.0.2) — [release notes](https://github.com/markedjs/marked/releases/tag/v17.0.2)
- Fixed list parsing when tabs are used. (17.0.2) — [release notes](https://github.com/markedjs/marked/releases/tag/v17.0.2)
- Fixed incorrect indentation handling for list items. (17.0.2) — [release notes](https://github.com/markedjs/marked/releases/tag/v17.0.2)
- Fixed strikethrough flanking-rule handling. (17.0.2) — [release notes](https://github.com/markedjs/marked/releases/tag/v17.0.2)
- Block elements in task items are handled correctly when parsing Markdown. (17.0.1) — [release notes](https://github.com/markedjs/marked/releases/tag/v17.0.1)

## marked 16

### Fixes and other changes

- Avoids RegExp lookbehind assertions, improving compatibility with runtimes that do not support them. (16.4.2) — [release notes](https://github.com/markedjs/marked/releases/tag/v16.4.2)
- Resolved an even-numbered backtick precedence issue in parsing. (16.4.1) — [release notes](https://github.com/markedjs/marked/releases/tag/v16.4.1)
