Release notes exist to answer one question for someone who does not read your code: what changed for me? Write the visible effect, not the internal fix. Skip the entry entirely if there isn't one. Everything else in this guide is detail underneath that.
This page is one part of a larger guide. For the whole subject in one place, see changelogs and release notes.
Who are release notes actually for?
Not for you, and not for the next engineer. Both of those audiences already have better tools: a commit log, a pull request, a diff. Release notes are for the person using the product who was not in the room when the work happened, and who is deciding, in about four seconds, whether this update is worth their attention.
Changelogs are for humans, not machines.
Keep a Changelog 1.1.0
That person usually falls into one of three groups: an existing user skimming to see if anything they rely on moved, a frustrated user checking whether the exact thing they complained about got addressed, or someone evaluating the product for the first time, reading the changelog as a proxy for whether it is actively maintained. None of the three is asking "how was this implemented."
Keep "what changed for the reader" in view and most of the common mistakes below stop happening on their own.
Why does "various bug fixes and improvements" fail everyone?
Because it answers a question nobody asked. Nobody wonders whether fixes happened; they wonder which ones, and whether one of them is the thing they reported. A line like that tells the reader precisely nothing, and it tells them that nothing else in the note was worth writing either, so they stop reading the rest of the release too.
It also fails you. A vague line does not build trust, does not close the loop with the person who filed the bug, and does not give search engines or AI crawlers anything to index. It is the release-notes equivalent of a shrug.
The fix costs almost nothing: name the thing. "Fixed a crash when exporting large PDFs" takes the same three seconds to write as "bug fixes" and gives the reader an actual answer.
How do you write the effect, not the fix?
The habit to build is translation: take the internal description of what changed and rewrite it as what the user now experiences. The internal description is usually written from the code's point of view. The release note has to be written from the reader's point of view.
| Internal description | Weak release note | Strong release note |
|---|---|---|
| Refactored the search index to use a trigram matcher | Improved backend search performance | Search now finds results even with a typo in your query |
| Fixed a race condition in the export queue worker | Fixed export bug | Fixed an issue where large exports sometimes finished with a blank last page |
| Added a debounce to the save handler | Optimised save behaviour | Typing no longer causes a brief lag before your changes save |
| Bumped the PDF rendering library to 3.2 | Updated dependencies | PDF exports now preserve embedded fonts correctly |
Notice the pattern: the internal description names a mechanism, and the strong version names a symptom the reader would recognise, and states plainly that it no longer happens. If you cannot describe the change without using an internal system name, a file name or a library version, you have not translated it yet.
How much detail does each audience actually need?
Less than you think, and the right amount depends on who is reading. A general release note aimed at all users needs one sentence: what changed, and what it means for them. A note attached to a specific bug report can go one sentence further, naming the exact circumstance that used to fail, so the person who reported it recognises their own bug.
Technical detail belongs in a linked pull request, an engineering blog, or nowhere, not in the note itself. If the release includes an internal migration, a dependency bump with no visible effect, or a refactor, that is real work and it deserves to happen, but it is not a release note unless it changed something the reader can see, click or notice.
A helpful test: if you deleted the entry, would a single user notice something now behaves differently that used to work the old way? If the answer is no, the entry should not exist as user-facing copy.
What tone and length actually work?
Plain and short. One sentence for most entries, two at most. Say what changed, in the same words your reader would use to describe the problem, not the words your codebase uses to describe the class or function.
Group entries by kind rather than commit order, so a reader scanning for "did they fix my thing" can jump straight to the right section. New features, improvements, and fixes are the three groups worth keeping separate; anything smaller is over-organising a changelog nobody asked to be organised twice.
Avoid two habits that creep in from engineering writing. The first is passive voice that hides who or what is affected: "an issue was resolved" tells the reader nothing about whether it affects them. The second is marketing language stapled onto a bug fix: a fixed crash is not "an enhanced stability experience", it is a fix, and calling it something else reads as evasive to anyone who hit the crash.
What do you write when nothing user-facing changed?
Nothing, in the changelog. Not every release needs an entry, and a release with internal-only changes, dependency bumps, or test coverage does not owe the reader a paragraph pretending otherwise.
Two honest options exist for that release. Skip the entry and let the version number simply move forward; most changelog readers will never notice a version bump with no corresponding note, because they are scanning for changes that affect them, not counting version numbers. Or, if your product publishes every release regardless, write one plain sentence that says so: "This release contains internal improvements with no visible changes." That line costs one sentence and is more honest than inventing three bullet points to fill space.
What you should never do is pad a quiet release with restated old entries, cosmetic rewording of a previous note, or a vague line invented to make the release look bigger than it was. A reader who catches that once stops trusting every future entry from you, including the ones that matter.
One payment, no subscription, unlimited products.
What does a well-organised release actually look like?
Group by kind, lead with the effect, and keep entries short enough to scan in a few seconds each.
New
- Search now finds results even with a typo in your query.
Improved
- Typing no longer causes a brief lag before your changes save.
Fixed
- Large exports no longer finish with a blank last page.
- PDF exports now preserve embedded fonts correctly.
That is the whole shape. Three groups, one line each, every line describing something the reader can notice. For worked examples of the same idea taken further, including how to link an entry back to the person who requested it, see release notes examples people actually read.
Once you have the copy right, the format it lives in matters too. The Keep a Changelog format gives these three groups a standard structure, so returning readers know where to look without relearning your layout every release.
Frequently asked questions
How long should a single release note entry be?
One sentence for most entries, two at most. State what changed and what it means for the reader; leave the mechanism out unless it is genuinely part of what changed for them, such as a new integration they now need to configure.
Should release notes mention internal refactors or dependency updates?
Only if they produced a visible effect. A dependency bump that fixed a rendering bug is worth a line about the rendering fix, written for the reader, not the library. A dependency bump with no visible effect belongs in the commit history, not the changelog.
What is the difference between a changelog and release notes?
In practice, not much: a changelog is usually the cumulative list, and release notes are the entry for one specific version. The writing advice is identical either way, since a changelog is just release notes stacked in order.
Should every release have a changelog entry?
No. A release with no user-facing change does not need an entry, and forcing one leads to padding, which trains readers to stop trusting the changelog. If your product publishes every version number regardless, one plain sentence saying nothing user-facing changed is honest and sufficient.
Who should write release notes, engineering or product?
Whoever is closest to what the user actually experiences, which is often product or support rather than the engineer who wrote the code. The engineer knows the mechanism; the person who has read the bug reports knows what the reader will recognise, and recognition is the whole job of a release note.