Keep a Changelog, actually implemented
5 min read updated
Keep a Changelog is a one-page convention for a CHANGELOG.md: newest version first, one section
per version with a number and an ISO date, entries grouped under six types (Added, Changed,
Deprecated, Removed, Fixed, Security), and an Unreleased section at the top for entries between
releases. Most teams that cite it implement about two thirds of it, and the third they drop is the
third that protects their users.
Olivier Lacan published Keep a Changelog in 2014 with a line that has aged better than most software writing: don’t let your friends dump git logs into changelogs. Ten years on it is the closest thing this corner of software has to a standard. It is worth reading the source rather than a summary of it; this is about the parts that get dropped.
What does Keep a Changelog ask for?
A CHANGELOG.md at the repo root, newest first, with one section per version. Each version carries
a number and an ISO date, and groups its entries under six types:
| Type | For | What dropping it costs |
|---|---|---|
| Added | New features | Nothing; nobody drops this one |
| Changed | Changes in existing behaviour | Readers find out a behaviour moved from an error |
| Deprecated | Features about to be removed | A removal becomes an incident instead of a scheduled event |
| Removed | Features removed in this release | Nobody can tell a removal from a bug |
| Fixed | Bug fixes | Nothing; nobody drops this one either |
| Security | Vulnerabilities | The one reader scanning for it cannot find it |
Plus an Unreleased section at the top, so there is somewhere to put an entry the moment it is
merged, and so anyone can see what is coming.
That is nearly all of it. The rest is the reasoning: entries are for humans, one entry per change, and the file is a document rather than a log.
Which parts of Keep a Changelog get dropped?
The Unreleased section, then four of the six types, Security among them, in that order.
Unreleased disappears first. It is the section with no deadline, so it is the one that stops
being maintained, and once it is gone entries get written at release time from commit history. That
is precisely the git-log dump the spec opens by warning about, arrived at gradually.
Changelog automation is mostly about keeping this section alive
without a person remembering to.
The six types collapse into two. Most real changelogs end up with Added and Fixed, because Changed and Deprecated require a judgement about what someone relied on. That judgement is the valuable part. Deprecated in particular is the only type that is a promise about the future, and dropping it is how a removal turns into an incident; the mechanics of keeping that promise are in how to deprecate an API.
Security stops being separate. A security fix filed under Fixed is invisible to the one reader who was scanning for it. Keep it distinct even when the fix is trivial, and especially when you would rather not draw attention to it.
What does the spec not answer?
It is a file format. It says nothing about the questions you hit immediately after adopting it:
- How does anyone find out? A file in a repo reaches contributors. It does not reach a customer who has never opened GitHub.
- What about products without versions? A continuously deployed service has no v4.2.0 to group by. Most teams substitute dates, which works, and the spec does not bless or forbid it.
- Who writes the entry? The spec assumes a human does. It does not say when.
- What about multiple audiences? One file serves developers. It does not serve the same content to a non-technical admin, and reformatting it by hand for them is where the duplication starts. Changelog vs release notes is the split the spec leaves you to make.
Common Changelog, a stricter fork of the idea, tightens some of this: it bans certain entry phrasings, requires a link to the change, and is opinionated about who the reader is. It is worth reading if the loose parts of Keep a Changelog are what your team keeps arguing about.
Can you automate Keep a Changelog without dumping git logs?
Yes: derive the draft from structured commits, put it in Unreleased with its type prefilled, and require a human to edit the wording before a release is cut. The spec’s warning is about output, not tooling. Deriving a draft from commits is fine. Publishing that draft unedited is the thing it objects to.
The machine handles collection and formatting, which it is good at. The human handles selection and phrasing, which it is not. Conventional commits covers the two-layer split this relies on, and which commit types map to which of the six categories above. Our changelog tools roundup covers what exists for the collection half.
Where does Keep a Changelog stop being enough?
It stops at distribution. Keep a Changelog is a good answer to “what should this file look like”. It is not an answer to “how do our users learn what changed”, because a Markdown file in a repo is a distribution strategy that only works if your users are contributors.
That is the gap most teams hit second: the file is fine, and nobody outside the team reads it. Solving it means the entries have to become data that can be rendered somewhere else, which is a different problem from formatting a file, and the reason changelog examples collects public changelog pages rather than repo files. Turning those entries into something people return to is covered in how to build a changelog page.
Adopt the spec anyway. It costs an afternoon, it makes the second problem tractable, and it is still the best one page written about this. A complete file laid out to it is in CHANGELOG.md: what goes in it.
FAQ
Is Keep a Changelog a standard? It is a convention with wide adoption, not a standard body’s specification. Tooling (release scripts, linters, parsers) assumes its shape often enough that following it buys compatibility.
What goes in the Unreleased section? Every entry for a change that has merged but not shipped in a numbered release. When a release is cut, the section is renamed to the version and date and a fresh empty Unreleased section goes above it.
Should a changelog use semantic versioning? Keep a Changelog recommends it and does not require it. Libraries and APIs benefit; a continuously deployed service usually substitutes dates, which the format accommodates.
Should Security fixes be in the changelog before they are public? Add the entry when the fix ships, with enough detail for an operator to act and no more. Delaying the entry until a coordinated disclosure date is normal; omitting it is not.
The technical claims in this article have not been independently reviewed. If something here is wrong, tell us and we will correct it.