TL;DR:
Lead with what the user can now do or no longer has to worry about, not with what the code did.
Group changes under plain headings, keep each line to one change, and link to help for anything that needs steps.
Read the draft as a user who has never seen the code: any term only your team knows gets rewritten.
After a small update ships, someone on the team pastes the commit list into a document and calls it release notes: "Refactor sync module. Bump dependency. Fix null check." Nobody outside the team understands it, so nobody reads it. Release notes are for the person using the product, and the only question they ask is "what is different for me?"
Collect the changes, then translate them
Start with the raw list from wherever your team tracks work: tickets, a merged-changes list, or your own memory of the week. Do not publish this list. For each item, ask three questions: who notices this, what did they experience before, and what happens now?
An item nobody can notice, such as an internal cleanup, usually does not belong in the notes. You can add one line like "Behind the scenes improvements" if you want to be honest that work happened, but do not fill space with it.
A structure that scans easily
A one line summary at the top: version number or date, and the headline change.
Short groups under plain headings, such as New, Improved and Fixed. Skip a group if it is empty.
One change per line, starting with what the user can do or sees.
A link next to any change that needs steps, pointing to your help page.
A note at the end if something requires action from the reader, such as updating or signing in again.
Worked example: release notes for a small update
Say a note taking app called Tally (an invented example) ships version 2.4 with three changes. The team's raw list reads: "Add search index for titles. Fix crash on empty tag. Update export lib."
Raw item | Who notices | Translation for users |
|---|---|---|
Add search index for titles | Anyone with many notes | Search now matches note titles first |
Fix crash on empty tag | People who saved a tag with no name | The app no longer closes if you create a tag with no name |
Update export lib | People exporting to PDF | Exported PDFs keep your line breaks (only if that is the user-visible effect) |
The last row is a warning: you may only claim an effect you have confirmed. If the ticket does not say what changed for the user, ask the person who wrote it before you publish.
The finished note, with a bad version for contrast:
Bad:
v2.4: Refactored search, patched null tag crash, updated dependencies.
Better:
Tally 2.4 (12 November)
Title search improved.
Improved
- Search now matches note titles first, so the note you want is near the top.
- Exported PDFs keep your line breaks.
Fixed
- The app no longer closes when you save a tag with no name.
Need help with export? See the export guide: /help/export/Check what the better version does: it opens with the headline, each line starts with the user's experience, and the one change that needs explaining has a link. The line count matches the change count: three raw items, three lines (the headline repeats the first).
Plain words, short lines
Use the words your users use. If the button says "Share", write "Share", not "distribution flow".
Prefer "You can now..." or the thing itself in the present tense: "Search finds titles first".
Cut adjectives that promise ("amazing", "powerful"). A concrete fact does the job.
Name the screen or button where the change lives so people can find it.
Keep a fixed voice across versions; people skim by habit.
Links that earn their place
A link is useful when a change needs steps or has a side effect. Link to the help page, not the ticket. Use text that says where it goes ("export guide"), not "click here". Check each link on a phone and in a private browser window before you publish, because a broken link in release notes is worse than none.
Before publishing, read the note aloud as someone who has never opened the code. Wherever you stumble, a word is probably internal. Then ask a colleague outside the engineering team to read it and tell you, in their own words, what changed. If their summary does not match yours, rewrite the line.
Finally, date it and keep every version in one place, newest first. People arrive looking for the change that broke their routine, and a clear dated list lets them find it in seconds.
Mistakes to avoid
Burying the one important change under ten minor ones. Put it first.
Listing a fix without saying what was broken, so readers do not know if it affected them.
Using ticket numbers or internal names as the only description.
Hiding a removed feature. If something goes away, say so plainly and say what to do instead.
Promising a date for something not finished.
Doing it faster
Put the template where the whole team can find it and make one person responsible for the last read before each release. A habit of five minutes per update beats a big rewrite once a year.
Keep a running notes file while you work: after each change, write the user-facing sentence immediately, when you remember what happened. At release time you only edit. A short template saved once (headline, Improved, Fixed, link) removes most of the blank page problem.
Frequently asked questions
How long should release notes be?
As long as the number of changes a user would care about, and no longer. A small update can be three lines.
Should I list every bug fix?
List the ones a user could have noticed. Group minor ones into a single line such as "Smaller fixes and improvements".
