# changelog-parser

> Change log parser for node.

Latest version **4.1.0** (published 2026-06-17) · ISC license · 0 weekly downloads

## Install

```sh
npm install changelog-parser
pnpm add changelog-parser
yarn add changelog-parser
bun add changelog-parser
```

Provides the command `changelog-parser`.

## Health

**Score 75/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; has provenance; recently updated; high maintenance score; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 4.1.0 |
| Published | 2026-06-17 |
| First published | 2015-03-02 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | >=22.12.0 |
| Dependencies | 1 |
| Unpacked size | 20.9 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 82 |
| Author | Nate Goldman |
| Maintainers | bret, ungoldman, kneemer |
| Keywords | CHANGELOG.md, changelog, parser, semantic, semver, versioning |

## Links

- npm: https://www.npmjs.com/package/changelog-parser
- Repository: https://github.com/ungoldman/changelog-parser
- Issues: https://github.com/ungoldman/changelog-parser/issues
- npm.io page: https://npm.io/package/changelog-parser

## Dependencies (1)

- [remove-markdown](https://npm.io/package/remove-markdown.md) ^0.6.4

## Alternatives

- [babylon](https://npm.io/package/babylon.md) — 5.1M weekly downloads
- [csscolorparser](https://npm.io/package/csscolorparser.md) — 3.7M weekly downloads
- [expr-eval-fork](https://npm.io/package/expr-eval-fork.md) — 1.5M weekly downloads
- [@leeoniya/ufuzzy](https://npm.io/package/@leeoniya/ufuzzy.md) — 247.7K weekly downloads
- [xml-parser](https://npm.io/package/xml-parser.md) — 78.4K weekly downloads

## Recent versions

- 4.1.0 (latest) — 2026-06-17
- 4.0.0 — 2026-06-15
- 3.0.1 — 2022-12-24
- 3.0.0 — 2022-12-21
- 2.8.1 — 2022-03-14
- 2.8.0 — 2019-05-03
- 2.7.0 — 2019-03-08
- 2.6.0 — 2018-12-18
- 2.5.1 — 2018-12-06
- 2.5.0 — 2018-04-30
- 2.4.0 — 2018-02-13
- 2.3.0 — 2018-01-09
- 2.2.0 — 2017-12-29
- 2.1.0 — 2017-12-12
- 2.0.5 — 2017-06-28
- … 8 more at https://npm.io/package/changelog-parser/versions

## README

<div align="center">

<img src="./log.png">

# changelog-parser

Change log parser for node.

[![npm][npm-image]][npm-url]
[![build][build-image]][build-url]
[![downloads][downloads-image]][npm-url]

[npm-image]: https://img.shields.io/npm/v/changelog-parser.svg
[npm-url]: https://www.npmjs.com/package/changelog-parser
[build-image]: https://github.com/ungoldman/changelog-parser/actions/workflows/tests.yml/badge.svg
[build-url]: https://github.com/ungoldman/changelog-parser/actions/workflows/tests.yml
[downloads-image]: https://img.shields.io/npm/dm/changelog-parser.svg

</div>

## Features

- Parses a `CHANGELOG.md` file (or raw text string) into a structured object: a title, an optional description, and an array of version entries.
- Extracts each version's number, date, body, and list items, grouped by `### subheading`.
- Promise-based, with a legacy Node-style callback also supported.
- Optionally strips markdown from parsed entries.

### Supported formats

These common changelog formats are officially supported:

- **[Keep a Changelog](https://keepachangelog.com/)**: `## [x.y.z] - YYYY-MM-DD` headings, `### Added` / `### Changed` / etc. sections
- **[Conventional Changelog](https://github.com/conventional-changelog/conventional-changelog)**: `## [x.y.z](compare) (date)` headings, with or without top-level title
- **[Release Please](https://github.com/googleapis/release-please)**: `## [x.y.z](compare) (date)` headings with `### ⚠ BREAKING CHANGES` section
- **[Standard Version](https://github.com/conventional-changelog/standard-version)**: headings set by release type (`#` major, `##` minor, `###` patch)
- **[auto-changelog](https://github.com/CookPete/auto-changelog)**: `#### [vx.y.z](compare)` headings with the date on a `> ...` blockquote line

Maintained with 100% test coverage, verified on Linux, macOS, and Windows across all supported Node.js versions.

## Install

```
npm install changelog-parser
```

## Usage

This module is [ESM-only](https://antfu.me/posts/move-on-to-esm-only). It exports a named `parseChangelog` function that parses a changelog and returns a `Promise`.

```js
import { parseChangelog } from 'changelog-parser'

// async / await
const changelog = await parseChangelog('path/to/CHANGELOG.md')

// or as a promise
parseChangelog('path/to/CHANGELOG.md')
  .then((changelog) => console.log(changelog))
  .catch((err) => console.error(err))
```

A default export of the same function is also available (`import parseChangelog from 'changelog-parser'`).

CommonJS consumers on Node.js >= 22.12 can still `require()` it, but the function is no longer the module itself:

```js
const { parseChangelog } = require('changelog-parser')
```

### Callback

A Node-style callback is also supported. It was the original interface (the package predates native promises) and is kept for backwards compatibility. New code should use the returned promise.

```js
parseChangelog('path/to/CHANGELOG.md', (err, result) => {
  if (err) throw err

  console.log(result)
})
```

### Options

The first argument can be a path string or an options object (`string | ChangelogOptions`). You must provide either `filePath` or `text`.

```ts
interface ChangelogOptions {
  /** Path to a changelog file. */
  filePath?: string
  /** Raw changelog text (alternative to `filePath`). */
  text?: string
  /** Strip markdown from parsed entries. Defaults to `true`. */
  removeMarkdown?: boolean
}
```

### Command-line interface

There is also a command-line interface available.

```shell
npx changelog-parser <path-to-changelog.md> # invoke with npx
npm install -g changelog-parser # or install globally
```

This installs a program called `changelog-parser` that you simply pass a `CHANGELOG.md` file.

```
changelog-parser path/to/CHANGELOG.md
```

This will print the JSON object representing the change log to the terminal.

Alternately you can run it without arguments and it will look for a `CHANGELOG.md` file in the working directory.

## Migrating from 3.x

As of v4.0.0 this package is ESM-only. The API and output are otherwise unchanged.

- **ESM**: `import parseChangelog from 'changelog-parser'`, or the named `import { parseChangelog }`.
- **CommonJS**: a bare `require('changelog-parser')` no longer returns the function. On Node 22.12+, where `require()` of an ES module is supported, use `const { parseChangelog } = require('changelog-parser')`. On older Node, use a dynamic `import()`. Node 22.12+ is only needed for this path.
- `body` and `description` are now always joined with `\n` rather than the OS line ending, so output no longer varies by platform.

## Output

`parseChangelog` resolves to (and the callback receives) a `Changelog`. These types are exported.

```ts
interface Changelog {
  /** The document title (the first `#` heading that is not itself a version), if present. */
  title?: string
  /** Free text between the title and the first version, if any. */
  description?: string
  /** Version entries, in document order. */
  versions: ChangelogVersion[]
}

interface ChangelogVersion {
  /** Semver string if the heading is semver-compliant, otherwise `null`. */
  version: string | null
  /** The raw heading text. */
  title: string | null
  /** Date parsed from the heading if present, otherwise `null`. */
  date: string | null
  /** All content under the heading, as a single string. */
  body: string
  /**
   * List items grouped by subheading. The `_` key holds every list item;
   * each `### Subheading` adds a key with the items beneath it.
   */
  parsed: Record<string, string[]>
}
```

For example, this changelog:

```markdown
# Changelog

## [1.1.0] - 2024-03-15

### Added

* A `format` option.

### Fixed

* Squashed a bug.

## [1.0.0] - 2024-01-01

* First release.
```

parses to:

```js
{
  title: 'Changelog',
  versions: [
    {
      version: '1.1.0',
      title: '[1.1.0] - 2024-03-15',
      date: '2024-03-15',
      body: '### Added\n\n* A `format` option.\n\n### Fixed\n\n* Squashed a bug.',
      parsed: {
        _: ['A format option.', 'Squashed a bug.'],
        Added: ['A format option.'],
        Fixed: ['Squashed a bug.']
      }
    },
    {
      version: '1.0.0',
      title: '[1.0.0] - 2024-01-01',
      date: '2024-01-01',
      body: '* First release.',
      parsed: { _: ['First release.'] }
    }
  ]
}
```

A version heading can be at any level (`#` through `######`). A `#` or `##` is always a version, except a `#` that is the document title (the first `#` heading that is not itself a version). At `###` and deeper, a heading is a version only when it looks like one, so conventional-changelog / standard-version patch headings (`###`) and auto-changelog version headings (`####`) are captured, while a `### Section` such as `### Added` is not.

The version number is read whether the heading is bare (`2.1.0`), `v`-prefixed (`v1.0.0`), or wrapped in brackets and optionally linked (`[0.9.0](...)`). It is `null` when the heading is not [semver](https://semver.org/)-compliant (such as `Unreleased`). Dates are recognized in common numeric formats (`YYYY-MM-DD`, `DD.MM.YYYY`, parenthesized `(YYYY-MM-DD)`) and textual English formats (`20 January 2021`, `January 20, 2021`). The date is taken from the heading, or from a `>` blockquote line directly beneath it when the heading carries none (as auto-changelog writes them).

`parsed` is flat: it captures one entry per top-level list item. Nested or indented sub-items are not split into their own entries, but the full original text (including any nesting) is always available in `body`.

## Contributing

Contributions welcome! Please read the [contributing guidelines](CONTRIBUTING.md) first.

## License

[ISC](LICENSE.md)

Log image is from [emojipedia](https://emojipedia.org/wood/).

---
_Source: https://npm.io/package/changelog-parser · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
