How to Write a Changelog in English
Learn the English conventions for writing a clear software changelog, covering categorization, audience-appropriate phrasing, and breaking change callouts.
A changelog written from commit messages reads like it was written for the author, not the reader — a good changelog is written for someone deciding whether to upgrade, which means translating internal implementation detail into user-relevant impact.
Key Vocabulary
Added / Changed / Fixed / Removed — the standard categorization headers, following conventions like Keep a Changelog, that group entries by what kind of change they represent, letting a reader scan for the category they actually care about. “Sort these entries under Added, Changed, Fixed, and Removed instead of one flat list — someone upgrading mainly cares whether anything was removed or changed in a breaking way, and flat lists make that hard to find quickly.”
Breaking change — a change that requires the consumer to modify their own code or configuration to keep working, which needs to be called out explicitly and prominently, not buried among routine fixes. “This needs a clear breaking change callout at the top, not buried in the Changed section — renaming this required config field means every existing user’s config breaks silently until they update it, and that deserves visibility.”
User-relevant impact (not implementation detail) — describing a change in terms of what the user experiences or needs to do differently, rather than describing internal code changes that don’t affect how the software is used. “Rewrite this entry — ‘refactored the internal caching layer’ describes implementation detail nobody using the library cares about. If it improved response times, say that: ‘improved average response time by 30% for repeated queries.’”
Migration note — a short explanation, sometimes with a code example, telling users exactly what to change in their own code to accommodate a breaking change, included directly in the changelog entry rather than in a separate document users might miss. “Add a migration note right under the breaking change entry — show the old function call and the new one side by side, so someone upgrading doesn’t have to go dig through documentation to figure out what changed.”
Common Phrases
- “Should this go under Added, Changed, or Fixed?”
- “Is this actually a breaking change, or is it backward compatible?”
- “Does this entry describe user-relevant impact, or is it just implementation detail?”
- “Does this breaking change need a migration note with an example?”
- “Would someone scanning this changelog understand what they need to do before upgrading?”
Example Sentences
Writing a well-categorized entry:
”### Fixed — Corrected an issue where date filters using a custom timezone returned results one day off near midnight. This affected any query using the timezone parameter with a non-UTC value.”
Calling out a breaking change clearly:
”### Breaking Change — The fetchUser(id) function now returns a Promise instead of accepting a callback. Existing callback-based calls will throw a deprecation error. See the migration note below for the updated syntax.”
Writing a migration note:
“Migration note: replace fetchUser(id, callback) with const user = await fetchUser(id). If you can’t use async/await in this context, wrap the call in fetchUser(id).then(callback) instead.”
Professional Tips
- Organize entries under standard headers like Added, Changed, Fixed, and Removed — a consistent structure lets readers scan for exactly the category they need instead of reading the whole log.
- Never bury a breaking change among routine entries — give it its own prominent section or a clear, unmissable label at the top of the relevant version.
- Translate every entry into user-relevant impact, not implementation detail — if a change doesn’t affect how the software is used or its behavior, it usually doesn’t belong in a user-facing changelog at all.
- Include a concrete migration note with every breaking change — showing the exact before-and-after code saves every single user from having to work it out themselves.
Practice Exercise
- Rewrite an implementation-detail-focused changelog entry to describe user-relevant impact instead.
- Draft a breaking change callout for a hypothetical renamed API parameter.
- Write a migration note showing before-and-after code for that breaking change.