TL;DR
changelogen is the UnJS changelog generator — generates changelogs from conventional commits, creates GitHub releases, bumps versions, and supports monorepos. conventional-changelog is the Angular-style changelog generator — parses commit messages following the Conventional Commits spec, powers semantic-release, highly configurable. auto-changelog generates changelogs from git history — no commit convention required, groups by version tags, simple and opinionated. In 2026: changelogen for modern projects with conventional commits, conventional-changelog for semantic-release pipelines, auto-changelog for simple projects without commit conventions.
Key Takeaways
- changelogen: ~500K weekly downloads — UnJS, GitHub releases, version bumping, monorepo
- conventional-changelog: ~5M weekly downloads — Angular convention, powers semantic-release
- auto-changelog: ~200K weekly downloads — no convention needed, tag-based, simple
- changelogen and conventional-changelog require Conventional Commits format
- auto-changelog works with any commit style
- changelogen has the best DX for modern release workflows
changelogen
changelogen — modern changelog generation:
CLI usage
# Generate changelog:
npx changelogen
# Generate and bump version:
npx changelogen --bump
# Generate, bump, and create GitHub release:
npx changelogen --release
# Full release workflow:
npx changelogen --release --push
# 1. Parses commits since last tag
# 2. Generates CHANGELOG.md
# 3. Bumps version in package.json
# 4. Creates git commit and tag
# 5. Creates GitHub release
# 6. Pushes to remote
Output format
## v1.2.0
### 🚀 Enhancements
- Add dark mode support (#123)
- Implement package search API (#125)
### 🩹 Fixes
- Fix memory leak in WebSocket handler (#124)
- Correct pagination offset calculation (#126)
### 📖 Documentation
- Update API reference (#127)
### 🏡 Chore
- Upgrade TypeScript to 5.6 (#128)
Configuration
// changelog.config.ts
export default {
// Commit types:
types: {
feat: { title: "🚀 Enhancements" },
fix: { title: "🩹 Fixes" },
perf: { title: "🔥 Performance" },
docs: { title: "📖 Documentation" },
chore: { title: "🏡 Chore" },
refactor: { title: "💅 Refactors" },
test: { title: "✅ Tests" },
build: { title: "📦 Build" },
ci: { title: "🤖 CI" },
},
// Scopes to exclude:
excludeAuthors: ["dependabot[bot]"],
// GitHub config:
repo: {
owner: "pkgpulse",
repo: "pkgpulse",
},
// Output:
output: "CHANGELOG.md",
}
Programmatic API
import {
generateMarkDown,
parseCommits,
getGitDiff,
loadChangelogConfig,
} from "changelogen"
const config = await loadChangelogConfig(process.cwd())
const rawCommits = await getGitDiff("v1.1.0") // Since last tag
const commits = parseCommits(rawCommits, config)
const markdown = await generateMarkDown(commits, config)
console.log(markdown)
conventional-changelog
conventional-changelog — Angular convention:
CLI usage
# Generate changelog (append to CHANGELOG.md):
npx conventional-changelog -p angular -i CHANGELOG.md -s
# First release (full history):
npx conventional-changelog -p angular -i CHANGELOG.md -s -r 0
# Presets: angular, atom, codemirror, conventionalcommits, ember, eslint, jquery, jshint
npx conventional-changelog -p conventionalcommits -i CHANGELOG.md -s
Output format (Angular preset)
## [1.2.0](https://github.com/org/repo/compare/v1.1.0...v1.2.0) (2026-03-09)
### Features
* **search:** add package search API ([#125](https://github.com/org/repo/issues/125)) ([abc1234](https://github.com/org/repo/commit/abc1234))
* **ui:** add dark mode support ([#123](https://github.com/org/repo/issues/123)) ([def5678](https://github.com/org/repo/commit/def5678))
### Bug Fixes
* **api:** fix memory leak in WebSocket handler ([#124](https://github.com/org/repo/issues/124)) ([ghi9012](https://github.com/org/repo/commit/ghi9012))
* **pagination:** correct offset calculation ([#126](https://github.com/org/repo/issues/126)) ([jkl3456](https://github.com/org/repo/commit/jkl3456))
### BREAKING CHANGES
* **api:** removed deprecated `/v1/search` endpoint
Programmatic API
import conventionalChangelog from "conventional-changelog"
// Stream-based:
conventionalChangelog({
preset: "angular",
releaseCount: 1, // Only latest release
}).pipe(process.stdout)
// With custom options:
conventionalChangelog({
preset: {
name: "conventionalcommits",
types: [
{ type: "feat", section: "Features" },
{ type: "fix", section: "Bug Fixes" },
{ type: "perf", section: "Performance" },
{ type: "docs", section: "Documentation", hidden: true },
],
},
})
With semantic-release
// .releaserc.json
{
"branches": ["main"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"@semantic-release/npm",
"@semantic-release/github",
"@semantic-release/git"
]
}
// semantic-release uses conventional-changelog internally:
// 1. @semantic-release/commit-analyzer — determines version bump
// 2. @semantic-release/release-notes-generator — generates release notes
// 3. @semantic-release/changelog — updates CHANGELOG.md
// All powered by conventional-changelog parsers
Conventional Commits format
feat(scope): add new feature → minor bump
fix(scope): fix a bug → patch bump
perf(scope): improve performance → patch bump
docs(scope): update documentation → no bump
chore(scope): maintenance task → no bump
BREAKING CHANGE: description → major bump
feat!: breaking feature → major bump
auto-changelog
auto-changelog — no convention needed:
CLI usage
# Generate changelog from git tags:
npx auto-changelog
# With options:
npx auto-changelog \
--output CHANGELOG.md \
--template keepachangelog \
--unreleased \
--commit-limit 50
# Prepend unreleased changes:
npx auto-changelog --unreleased
Output format
# Changelog
## [Unreleased]
- Add dark mode support [`abc1234`](https://github.com/org/repo/commit/abc1234)
- Fix memory leak [`def5678`](https://github.com/org/repo/commit/def5678)
## [v1.1.0] - 2026-03-01
- Add package search API [`ghi9012`](https://github.com/org/repo/commit/ghi9012)
- Implement WebSocket connections [`jkl3456`](https://github.com/org/repo/commit/jkl3456)
- Fix pagination bug [`mno7890`](https://github.com/org/repo/commit/mno7890)
## [v1.0.0] - 2026-02-01
- Initial release
Configuration
// .auto-changelog (or package.json "auto-changelog" field)
{
"output": "CHANGELOG.md",
"template": "keepachangelog",
"unreleased": true,
"commitLimit": false,
"backfillLimit": false,
"hideCredit": false,
"sortCommits": "date",
"startingVersion": "v1.0.0",
"ignoreCommitPattern": "^(chore|docs|ci):",
"tagPattern": "v[\\d+\\.]+",
"breakingPattern": "BREAKING CHANGE:"
}
Templates
# Built-in templates:
npx auto-changelog --template compact
npx auto-changelog --template keepachangelog
npx auto-changelog --template json
# Custom Handlebars template:
npx auto-changelog --template ./my-template.hbs
No commit convention required
auto-changelog works with ANY commit style:
"Fixed the login page" ✅ Works
"feat: add dark mode" ✅ Works
"WIP: stuff" ✅ Works
"Merge pull request #123" ✅ Works (shows PR)
Groups commits by git tag (version):
v1.2.0 → all commits since v1.1.0
v1.1.0 → all commits since v1.0.0
No parsing of commit types — just chronological grouping.
Feature Comparison
| Feature | changelogen | conventional-changelog | auto-changelog |
|---|---|---|---|
| Commit convention required | ✅ | ✅ | ❌ |
| Version bumping | ✅ | ❌ (use standard-version) | ❌ |
| GitHub releases | ✅ | ❌ (use semantic-release) | ❌ |
| Monorepo support | ✅ | ⚠️ (with plugins) | ❌ |
| Custom templates | ❌ | ✅ | ✅ (Handlebars) |
| Presets | ❌ | ✅ (angular, etc.) | ✅ (compact, keepachangelog) |
| Programmatic API | ✅ | ✅ | ❌ |
| TypeScript | ✅ | ✅ | ❌ |
| Emoji categories | ✅ | ❌ | ❌ |
| semantic-release | ❌ | ✅ (powers it) | ❌ |
| Weekly downloads | ~500K | ~5M | ~200K |
When to Use Each
Use changelogen if:
- Want a modern all-in-one release tool (changelog + bump + GitHub release)
- Use conventional commits and want emoji-categorized output
- Working with monorepos (UnJS ecosystem)
- Want the simplest release workflow
Use conventional-changelog if:
- Using semantic-release for automated releases
- Need Angular/conventional commit parsing
- Want customizable presets and templates
- Building CI/CD pipelines with automated versioning
Use auto-changelog if:
- Don't follow a commit convention
- Want changelogs grouped by git tags
- Need the simplest possible setup (just run it)
- Prefer keep-a-changelog format
Methodology
Download data from npm registry (weekly average, February 2026). Feature comparison based on changelogen v0.5.x, conventional-changelog-cli v5.x, and auto-changelog v2.x.
Conventional Commits and Semantic Versioning Automation
The power of changelogen and conventional-changelog comes from the Conventional Commits specification — a lightweight convention on top of commit messages that makes it possible to determine the appropriate semver bump automatically. A feat: commit means a minor bump, a fix: commit means a patch bump, and any commit with BREAKING CHANGE: in the body (or a ! suffix like feat!:) means a major bump.
This is not just aesthetic discipline — it enables a fully automated release pipeline where humans never touch version numbers. With conventional-changelog powering semantic-release, every merged PR triggers an analysis of new commits, a calculated version bump, a generated changelog entry, and a published npm package — all without manual intervention. Teams that fully commit to this workflow report that it eliminates a category of release mistakes (forgotten changelog entries, wrong version bumps, late-tagged releases) entirely.
changelogen takes a slightly different approach by bundling the version bump, changelog generation, and GitHub release creation into a single npx changelogen --release --push command. This is simpler for teams that prefer a manual release trigger (run the command when you're ready to release) over fully automated CI releases. The tradeoff is that someone still has to remember to run it.
For teams not following any commit convention, auto-changelog provides a useful bridge: it groups commits by git tag without parsing commit types, giving you a chronological record of changes per release that is better than no changelog at all. When a team later adopts conventional commits, they can migrate to changelogen or conventional-changelog and generate richer output going forward while keeping the tag-based history.
Monorepo Release Workflows
Monorepos introduce changelog complexity that single-package tools handle poorly. When a repository contains ten packages and a single commit touches three of them, each package deserves a changelog entry only for commits relevant to it.
changelogen has native monorepo support via scoped commits. A commit formatted as fix(pkg-a): correct null handling maps to package pkg-a's changelog, while feat(pkg-b): add streaming API appears only in pkg-b's. npx changelogen --release in a monorepo context generates separate changelogs per package and bumps each independently.
conventional-changelog powers Lerna and changesets via its parsing library. The @changesets/cli tool — now the dominant monorepo release tool in 2026 — uses a different model: developers write explicit "changeset" files describing their changes rather than relying on commit message parsing. Under the hood, changesets uses conventional-changelog's parser to validate commit formats when configured to do so.
auto-changelog has no monorepo support. It generates a single CHANGELOG.md for the entire repository based on git tags, which creates noise in monorepos where each package has its own version and release cycle.
For new monorepos in 2026, the changesets workflow is worth evaluating alongside changelogen. It requires more explicit action from contributors (running pnpm changeset before merging) but produces more reliable and intentional version bumps, particularly in projects where a single commit might affect packages at different severity levels.
CI/CD Integration and GitHub Releases
The changelog generation step typically lives in CI, and the three tools have different integration stories for common CI platforms.
changelogen's --release flag creates a GitHub release using the GITHUB_TOKEN environment variable (standard in GitHub Actions). A minimal release workflow is just two steps: run tests, then npx changelogen --release --push. changelogen handles the git tag, the CHANGELOG.md update, the version bump commit, and the GitHub release object automatically. The GitHub release body is generated from the same commit parsing used for CHANGELOG.md, so they stay in sync.
conventional-changelog is rarely run in CI on its own — it's most commonly used as part of semantic-release. Setting up semantic-release requires a configuration file (.releaserc.json) and several plugins, but the result is a completely hands-off release pipeline. Every push to main (or your configured branch) triggers semantic-release analysis, and a release happens automatically when there are releasable commits.
auto-changelog integrates simply: add npx auto-changelog --output CHANGELOG.md to your CI release script before tagging. Because it requires no GitHub token or release API calls (it only reads git history and writes a file), it works in any CI environment without special credentials. For projects that just want a CHANGELOG.md file to ship with their npm package, auto-changelog's simplicity is an asset.
The choice between these three tools ultimately depends on how much automation you want and how tightly you follow the Conventional Commits specification. changelogen hits the sweet spot for projects that want automated releases without the full complexity of semantic-release — especially in the UnJS and Nuxt ecosystem where it is already the standard. conventional-changelog powers semantic-release and is the right choice when you want a fully hands-off release pipeline that publishes to npm automatically after every qualifying commit. auto-changelog is the pragmatic choice for projects that just need a well-formatted CHANGELOG.md generated from git history, with no other automation needed and no dependency on commit message conventions.
Changelog tooling decisions have downstream effects on team culture around releases. Teams that adopt changelogen or conventional-changelog alongside enforced commit conventions tend to develop more intentional release practices — the requirement to write feat: or fix: prefixes encourages thinking about whether a change is user-facing before merging it. auto-changelog removes this friction but also removes this forcing function. For open-source libraries where changelogs are read by downstream maintainers deciding whether to upgrade, investing in conventional commits and a tool that produces clean categorized output pays back in user trust. For internal services where changelog consumers are a small team, auto-changelog's simplicity often outweighs the discipline overhead of commit conventions.
Compare release tooling and developer utilities on PkgPulse →
See also: cac vs meow vs arg 2026 and cosmiconfig vs lilconfig vs conf, archiver vs adm-zip vs JSZip (2026).