Introduction
conventional-changelog reads your git history and turns it into a CHANGELOG.md, grouping commits into sections like Features and Bug Fixes. You write meaningful commit messages following a convention, and the tool assembles the release notes for you.
To do this, the tool needs to understand the shape of your commit messages. That structure comes from a commit convention — most commonly Conventional Commits — which is applied through a preset.
Quick start
Section titled “Quick start”-
Install
conventional-changelog:pnpm add -D conventional-changelognpm i -D conventional-changelogyarn add -D conventional-changelog -
Choose a preset. A preset teaches the tool how to parse and group your commits. Since we’re following Conventional Commits, install the matching preset:
pnpm add -D conventional-changelog-conventionalcommitsnpm i -D conventional-changelog-conventionalcommitsyarn add -D conventional-changelog-conventionalcommitsFollowing a different convention? See all available presets.
-
Make commits following the convention as you work:
feat(api): add async write() generatorfix(cli): resolve config path relative to cwdperf(parser): cache compiled header regex -
Run the generator with your preset. The
conventionalcommitsalias resolves to theconventional-changelog-conventionalcommitspackage you just installed:pnpm conventional-changelog -p conventionalcommitsnpx conventional-changelog -p conventionalcommitsyarn conventional-changelog -p conventionalcommitsAdd
--stdoutto print the result to the terminal instead of writing the file. -
Get your changelog. A new section is prepended to
CHANGELOG.md(existing entries are kept), using theversionfrom yourpackage.json:CHANGELOG.md ## [1.1.0](https://github.com/acme/app/compare/v1.0.0...v1.1.0) (2026-07-01)### Features* **api:** add async write() generator ([0f7e2c1](https://github.com/acme/app/commit/0f7e2c1a9d3e4b5c6f7089abcdef0123456789ab))### Bug Fixes* **cli:** resolve config path relative to cwd ([a3b9d84](https://github.com/acme/app/commit/a3b9d8472e1f0c9b8a7d6e5f4c3b2a1908f7e6d5))### Performance Improvements* **parser:** cache compiled header regex ([c1d2e3f](https://github.com/acme/app/commit/c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0))
By default the version comes from the closest package.json, only commits made since the last semver tag are included, and the result is written to CHANGELOG.md. When package.json has a repository field, versions and commit hashes link to your git host (as above); without it, they are plain text.
Available presets
Section titled “Available presets”A preset maps a commit convention to the parsing rules and changelog layout the tool uses. Install the one that matches your commits and pass its name to --preset (or -p):
| Preset | Package | Convention |
|---|---|---|
conventionalcommits | conventional-changelog-conventionalcommits | Conventional Commits |
angular | conventional-changelog-angular | Angular commit convention |
Common tasks
Section titled “Common tasks”Regenerate the whole changelog
Section titled “Regenerate the whole changelog”The first time you adopt the tool, generate notes for every release at once. --release-count 0 (or -r 0) rebuilds the full history and overwrites the output file:
pnpm conventional-changelog -p conventionalcommits -r 0npx conventional-changelog -p conventionalcommits -r 0yarn conventional-changelog -p conventionalcommits -r 0Generate for a specific range
Section titled “Generate for a specific range”Limit generation to a commit range with --from and --to (each accepts a tag or SHA):
pnpm conventional-changelog -p conventionalcommits --from v1.0.0 --to HEADnpx conventional-changelog -p conventionalcommits --from v1.0.0 --to HEADyarn conventional-changelog -p conventionalcommits --from v1.0.0 --to HEADProgrammatic usage
Section titled “Programmatic usage”Prefer to generate changelogs in code? The same result is available through the JS API:
import { ConventionalChangelog } from 'conventional-changelog'
const generator = new ConventionalChangelog() .readPackage() .loadPreset('conventionalcommits')
for await (const chunk of generator.write()) { process.stdout.write(chunk)}