How to write a changelog (with examples)
A changelog is a dated, per-version list of what changed in your software, written so the people who use it can tell what is different. To write a good one, group changes by type, describe the effect on the reader instead of the code, put the newest version first, and flag anything that breaks existing behaviour.
Most teams know they should keep one and still skip it, because the blank page is the hard part. This guide gives you a structure to fill in, six habits that make entries worth reading, and a before and after example you can copy.
Who reads a changelog
Before you write a line, decide who the entry is for. A changelog usually has four kinds of readers:
- Users who want to know whether a bug they hit is fixed or a feature they asked for exists.
- Developers who integrate with you and need to know what could break their code.
- Support and sales who answer "when did this change?" and need a date.
- Your future self, trying to remember why behaviour changed three versions ago.
If your audience is mostly end users, keep entries short and free of internal terms. If it is mostly developers, include identifiers and links. Our guide on changelogs versus release notes explains when to write both.
Why a commit log is not a changelog
It is tempting to paste the output of git log and call it done. Commit messages are written for maintainers, in the moment, and they describe how the code changed rather than what changed for the reader. They also include work nobody outside the team cares about: dependency bumps, refactors and typo fixes.
The Keep a Changelog guide makes the same point: using commit log diffs as changelogs is a bad idea because they are full of noise.
A changelog is an editorial product. Someone has to decide which changes matter, group them, and say them in plain language. That judgement is the whole job.
Six habits of a useful changelog
1. Write for the reader, not the codebase
Describe the effect, not the implementation. "Export any report to PDF" tells a user what they can do. "Add PDF exporter service" tells them nothing.
2. Group changes by type
Readers scan for what they care about. Headings such as Added, Changed, Fixed, Removed and Security let them jump straight there. The Keep a Changelog template uses exactly these groups and is a good default.
3. Put the newest version first, with a date
People arrive wanting the latest news. Put the newest release at the top and give every version an unambiguous date, ideally in the ISO format YYYY-MM-DD, so it reads the same in every country.
4. Call out breaking changes and say what to do
A removed option or a renamed setting deserves its own line near the top of the entry. Say what changed and what the reader should do about it. If you follow semantic versioning, a breaking change is also your signal to increase the major version.
5. Link to the detail
Keep each entry to one line and link the pull request or issue for readers who want depth. That keeps the changelog scannable without hiding the evidence.
6. Leave out the noise
Dependency bumps, internal refactors, formatting changes and test-only commits rarely belong. The exception is a dependency update that fixes a security problem or changes behaviour for users.
Before and after: from commits to a changelog entry
Here are six commits from a release, exactly as they appear in the log:
a3f9c21 feat: add pdf export (#142)
7be04d8 fix: oauth redirect loop (#139)
51c2e90 chore: bump deps
e8d1b37 feat: export button in toolbar
0f6a4c2 fix: typo in settings
92b7d15 refactor: report serviceTwo of them are features and one is a bug fix that users will notice. The rest are maintenance. Written for the reader, the entry becomes:
## 1.2.0 - 2026-10-12
### Added
- Export any report to PDF from the toolbar (#142)
### Fixed
- Signing in no longer sends you back to the login page in a loop (#139)Notice what happened. The two feature commits merged into one line, because the toolbar button is part of the same capability. The typo, the refactor and the dependency bump disappeared. The bug fix lost its jargon. You can see more finished examples of both user-facing and developer-facing entries on our examples page.
A checklist before you publish
- Is every entry a change the reader could notice or must act on?
- Is the version number and the date correct?
- Are breaking changes at the top, with what to do about them?
- Does each line read without knowing the codebase?
- Does each important line link to its pull request or issue?
- Could someone find the changelog without asking you where it is?
Where to publish it
You can publish the same content in more than one place:
- A file in the repository, usually
CHANGELOG.md, which suits developers and open source projects. - A public page on your website, which suits customers and is easy to share and search.
- Inside the product, as a short "What's new" notice, which reaches people while they are using it.
Making it a habit
The best changelog process is the one your team will actually follow. Two approaches work well. You can keep an Unreleased section and add a line with every merged pull request, so the work is spread across the release. Or you can draft the entry at release time from the list of merged changes, then edit it by hand.
If the drafting step is what slows you down, a tool can help. ReleaseTale reads the commit messages, pull request titles and descriptions, and file names for the commits you pick, then writes a first draft in two versions. You still review and edit it before you save, which is the part that keeps it accurate.