DEV Community

Belal Zahran
Belal Zahran

Posted on • Originally published at changelog-generator-orcin.vercel.app

How Top Open Source Projects Write Changelogs (And How to Automate Yours)

Nobody reads changelogs. Until something breaks.

Then suddenly your changelog is the most important document in the repository. Users need to know what changed, when, and why. Contributors need to understand the project's direction. And you — the maintainer — need a historical record that doesn't require archaeological dig through git log.

I maintain three open source projects. The one with a good changelog gets 70% fewer "what changed?" issues. Here's what I've learned about writing changelogs that actually serve their purpose.

What Makes a Good Changelog

The Keep a Changelog project nailed the definition: "A changelog is a file which contains a curated, chronologically ordered list of notable changes for each version of a project."

The key word is curated. A changelog is not a git log dump. It's a human-readable summary of what matters to users.

The Gold Standard: React's Changelog

React's changelog is widely regarded as one of the best in open source. Here's why:

## 18.3.0 (April 25, 2024)

### React

- Add ref cleanup function support
- Warn about deprecated string refs
- Deprecate `defaultProps` for function components

### React DOM

- Fix hydration error messages to include the component stack
- Support `fetchPriority` on images
Enter fullscreen mode Exit fullscreen mode

Notice what they do well:

  • Grouped by package (for monorepos)
  • Action-oriented language — "Add," "Fix," "Deprecate"
  • User-focused — describes what changes mean, not implementation details
  • Concise — each item is one line

The Anti-Pattern: Git Log Dump

Here's what bad changelogs look like:

## v2.1.0
- 4a2f8bc fix typo in readme
- 8d1e3af update dependencies
- 2c9f1be refactor internal utils
- 7b3d4ea fix the thing
- 1e5a2cd more fixes
- 9f8c3ba WIP
- 3d2a1ef merge branch 'feature-x'
Enter fullscreen mode Exit fullscreen mode

This tells users nothing. Internal commits, WIP messages, merge commits — none of this helps someone decide whether to upgrade.

The Changelog Structure That Works

After studying dozens of well-maintained projects, here's the structure I recommend:

# Changelog

## [Unreleased]

## [2.1.0] - 2026-03-20

### Added
- New CSV export option for reports (#142)
- Dark mode support for dashboard

### Changed
- Improved search performance by 40%
- Updated minimum Node.js version to 20

### Fixed
- Fixed date picker not working in Safari (#138)
- Fixed memory leak when processing large files

### Deprecated
- `legacyMode` option will be removed in v3.0

### Removed
- Dropped support for Node.js 16

### Security
- Updated `xmldom` dependency to fix CVE-2024-XXXX
Enter fullscreen mode Exit fullscreen mode

The six categories (Added, Changed, Fixed, Deprecated, Removed, Security) cover every type of change a user needs to know about.

Writing Good Changelog Entries

Rule 1: Write for Users, Not Developers

Bad: "Refactored the query builder to use prepared statements"
Good: "Fixed SQL injection vulnerability in search feature"

Your users don't care about your implementation choices. They care about what's different for them.

Rule 2: Lead with the Action

Start every entry with a verb: Added, Fixed, Changed, Removed, Improved, Updated.

Bad: "The API now supports pagination"
Good: "Added pagination support to the API (default: 50 items per page)"

Rule 3: Include Issue/PR References

- Fixed file upload failing for files over 10MB (#234)
Enter fullscreen mode Exit fullscreen mode

This lets users quickly find the full context if they need it.

Rule 4: Highlight Breaking Changes

Breaking changes should be impossible to miss:

### Changed
- **BREAKING**: Renamed `getUser()` to `fetchUser()` — see migration guide
- **BREAKING**: Minimum Node.js version is now 20 (was 16)
Enter fullscreen mode Exit fullscreen mode

Automating Changelog Generation

Writing changelogs manually is tedious. Here's how to automate without losing quality.

Approach 1: Conventional Commits

If your team uses Conventional Commits, tools can auto-generate changelogs from commit messages:

feat: add CSV export option
fix: resolve Safari date picker issue (#138)
perf: improve search performance by 40%
BREAKING CHANGE: rename getUser() to fetchUser()
Enter fullscreen mode Exit fullscreen mode

Tools like standard-version or semantic-release parse these prefixes and generate changelog entries automatically.

The downside: this only works if everyone on the team follows the convention consistently. In my experience, it takes about a month before it becomes habit.

Approach 2: PR-Based Changelogs

GitHub Actions can generate changelog entries from PR titles and labels:

  1. Label PRs with feature, bugfix, breaking, etc.
  2. On release, a workflow collects all merged PRs since the last tag
  3. Groups them by label and generates the changelog

This is how projects like Next.js and Tailwind do it.

Approach 3: AI-Assisted Generation

For projects where you haven't been following conventions from the start, AI can help bridge the gap. Feed your recent commits and diffs to an AI tool, and it can generate human-readable changelog entries.

Changelog Generator does exactly this — you point it at your git history, and it produces a structured changelog with proper categorization. It's particularly useful for catching up on changelog debt when you've been shipping features without documenting changes.

Approach 4: Hybrid

The most practical approach for most teams:

  1. Use conventional commits for structure
  2. Auto-generate a draft changelog on each release
  3. Have a human review and edit the draft before publishing

The automation handles the tedium; the human ensures quality.

Changelog Tips from Real Maintainers

I talked to several open source maintainers about their changelog practices:

"Write the changelog entry when you write the code." — Don't try to reconstruct what changed from a list of commits three weeks later. Add a changelog entry as part of each PR.

"Changelogs are documentation, not celebration." — Resist the urge to hype features. Users reading a changelog want information, not marketing.

"Version numbers are for computers; changelogs are for humans." — Your semver tells machines about compatibility. Your changelog tells humans what to expect.

"If you have to choose between detailed and up-to-date, choose up-to-date." — A brief, current changelog is infinitely more useful than a detailed, abandoned one.

Setting Up Changelog Automation in 10 Minutes

Here's the quickest path to automated changelogs:

# Install standard-version
npm install --save-dev standard-version

# Add to package.json scripts
"scripts": {
  "release": "standard-version"
}

# First release
npx standard-version --first-release

# Subsequent releases
npm run release
Enter fullscreen mode Exit fullscreen mode

This will:

  1. Bump the version based on commit types
  2. Generate/update CHANGELOG.md
  3. Create a git tag

The Changelog Checklist

Before publishing any release:

  • [ ] All user-facing changes are documented
  • [ ] Breaking changes are clearly marked
  • [ ] Entries are written from the user's perspective
  • [ ] Version number follows semver
  • [ ] Date is included
  • [ ] Issue/PR references are linked where relevant
  • [ ] Security fixes are called out explicitly

Your changelog is a contract with your users. Keep it honest, keep it current, and they'll trust your project with their production code.

Need to generate a changelog from your git history? Try it free at changelog-generator-orcin.vercel.app.

Top comments (0)