How to write a changelog people actually read
How to write a changelog: the Keep a Changelog format, a CHANGELOG.md example, GitHub release notes, and how to turn updates into launch-worthy news.

To write a changelog, list every notable change per version, newest first, with a release date, grouped under Added, Changed, Deprecated, Removed, Fixed, and Security. Write for the people who use the product, not for the commit history. Keep it in a CHANGELOG.md file for developers, publish a readable version on your site for customers, and reuse the biggest entries as build-in-public posts and relaunch reasons.
To write a changelog, record each notable change for each release in plain language, newest first, dated, and grouped by type of change. A good changelog answers one question for a user in seconds: what is different since I last looked, and does it affect me?
It is also one of the cheapest marketing assets a small product has. Every entry is proof that the product is alive.
The Keep a Changelog format
Keep a Changelog is a widely used, open convention. Its guiding principles: changelogs are for humans, not machines; every version gets an entry; the latest version comes first; each release shows its date; and similar changes are grouped together under these types:
| Type | Use it for |
|---|---|
| Added | New features |
| Changed | Changes to existing functionality |
| Deprecated | Features that will be removed soon |
| Removed | Features that are now gone |
| Fixed | Bug fixes |
| Security | Fixes for vulnerabilities |
- TypeAdded
- Use it forNew features
- TypeChanged
- Use it forChanges to existing functionality
- TypeDeprecated
- Use it forFeatures that will be removed soon
- TypeRemoved
- Use it forFeatures that are now gone
- TypeFixed
- Use it forBug fixes
- TypeSecurity
- Use it forFixes for vulnerabilities
It also recommends an Unreleased section at the top, where changes collect until the next release, and dates in the ISO 8601 format (2026-11-12).
A CHANGELOG.md example
Keep a Changelog suggests naming the file CHANGELOG.md, the name people look for alongside files like the README. Most projects keep it in the repository root:
# Changelog
All notable changes to this project are documented in this file.
The format is based on Keep a Changelog.
## [Unreleased]
### Added
- Export invoices as CSV.
## [1.4.0] - 2026-11-12
### Added
- Recurring invoices that send on a schedule.
### Changed
- The dashboard now opens on overdue invoices.
### Fixed
- PDF totals no longer round to the nearest dollar.Each line is written from the user’s side: what they can now do, or what stopped going wrong. "Refactor invoice service" is a commit message. "PDF totals no longer round to the nearest dollar" is a changelog entry.
Changelog file vs commit history
Keep a Changelog puts it bluntly: "Don’t let your friends dump git logs into changelogs." A commit log is full of merges, typo fixes, and internal changes nobody outside the team cares about. The changelog is the edited version: only notable changes, in words a customer understands.
A simple habit keeps this cheap. Add a line under Unreleased in the same pull request that makes the change. At release time, rename Unreleased to the version and date.
How to write a changelog in GitHub
GitHub Releases can generate release notes for you. When you draft a release and click Generate release notes, GitHub lists the merged pull requests, the contributors, and a link to the full diff. A .github/release.yml file lets you group pull requests into categories by label and exclude labels or bots such as dependency updates.
Generated notes are a useful starting point, but they are still a list of pull requests. Edit them into user-facing language before publishing. Keep a Changelog also points out that GitHub Releases only live on GitHub, so keep a CHANGELOG.md too if your users are not developers browsing your repository.
A changelog for customers, not just developers
For a SaaS product, most users will never open your repository. Give them a public changelog page on your site, built from the same entries but written a little more warmly:
- Lead with the benefit. "You can now schedule recurring invoices" beats "Added recurring invoices".
- Add a screenshot or short clip for anything visual.
- Say who asked for it, with permission. It shows users that feedback goes somewhere.
- Link to the feature, so readers can try it straight away.
- Keep a steady rhythm. Weekly or every two weeks is easier to maintain than a big monthly post.
Use your changelog for build in public and relaunches
Every meaningful entry is a post waiting to happen. One shipped feature, the reason you built it, and a screenshot is a strong build-in-public update. Our guide to building in public on X covers how to turn shipping into a following.
A changelog also tells you when a relaunch is justified. When several entries add up to a real reason to look again, such as a missing integration, a shorter onboarding, or a new audience, that is a relaunch story. If your launch went quiet, the stalled launch guide explains how to relaunch around a real change rather than a new date.
Frequently asked questions
What should a changelog include?
Every notable change per version, newest first, with a release date, grouped under Added, Changed, Deprecated, Removed, Fixed, and Security. Leave out internal refactors and changes users will never notice.
What should the changelog file be called?
CHANGELOG.md, usually in the root of the repository. Some projects use HISTORY, NEWS, or RELEASES, but CHANGELOG.md is what people look for.
Can GitHub generate a changelog automatically?
Yes. GitHub Releases can generate release notes listing merged pull requests, contributors, and a link to the full changelog, and a .github/release.yml file groups them by label. Edit them into user-facing language before publishing.
How often should I update my changelog?
Add entries as you merge changes, and publish with every release. For a customer-facing changelog, a weekly or fortnightly update is a sustainable rhythm.
Shipped something big? Give it a relaunch.
Relaunch on DanielLaunches with a permanent product page and real visitor and click numbers that show whether the update landed.
Get my roadmapRead next
Sources
- Keep a Changelog 1.1.0 - guiding principles, change types, the Unreleased section, and naming the file CHANGELOG.md
- GitHub Docs: Automatically generated release notes - how generated release notes work and how release.yml groups pull requests by label