How to Write Technical Release Notes
Learn how to write clear technical release notes: breaking changes, added/changed/fixed/removed sections, versioning, audience, and examples from Stripe and GitHub.
Release notes are often the first thing a developer reads after a software update. They communicate what changed, what broke, what was fixed, and what new capabilities are available. Written well, release notes build trust and reduce support burden. Written poorly, they generate confusion, missed migrations, and angry developers. This guide explains how to write excellent technical release notes in English.
Know Your Audience
Before you write a single word, identify who will read your release notes.
- SDK users need to know about API changes that affect their code.
- Platform operators need to know about infrastructure or configuration changes.
- End users need to understand changes in terms of features and behaviour, not implementation details.
Most technical release notes target developers integrating with an API or maintaining a dependency. Write for that audience: precise, specific, and respectful of their time.
The Keep a Changelog Format
The Keep a Changelog format is the most widely adopted standard for technical release notes. It organises changes into labelled sections:
- Added — new features
- Changed — changes to existing functionality
- Deprecated — features that will be removed in a future release
- Removed — features removed in this release
- Fixed — bug fixes
- Security — vulnerability fixes
Example from Stripe-style release notes:
Added
- Added
PaymentIntent.capture_methodsupport for split capture flows.- The
chargesendpoint now acceptsmetadataarrays of up to 50 key-value pairs (previously 20).Changed
Invoice.due_datenow defaults tonullwhen no due date is set, rather than returning the creation date.Fixed
- Fixed an issue where webhook retries could trigger duplicate
payment_intent.succeededevents in edge cases involving network timeouts.Removed
- Removed the
sourcefield fromPaymentIntentobjects. Usepayment_methodinstead.
Breaking Changes — Handle with Care
Breaking changes are the most critical thing to communicate. A breaking change is any change that requires existing consumers to modify their code to continue functioning correctly.
Always:
- Call out breaking changes at the top of the release notes or in a dedicated section
- Explain exactly what changed and what the developer must do
- Provide a migration path or link to a migration guide
- Give advance warning in the previous release (deprecation) whenever possible
“Breaking change: The
user.get()method no longer accepts positional arguments. Update all calls fromuser.get(userId)touser.get(id=userId). Positional argument support was deprecated in v2.4 and has been removed in v3.0.”
Versioning Context
State clearly which version the notes apply to, and reference the previous version so developers understand the delta.
“Version 4.2.0 — released 2026-06-14 (previous: 4.1.3)”
Follow Semantic Versioning (SemVer) conventions:
- Major (4.0.0) — breaking changes
- Minor (4.2.0) — new features, backwards compatible
- Patch (4.2.1) — bug fixes, backwards compatible
If your release increments the major version, the developer’s first question will be “what broke?” — answer it prominently.
What Good Release Notes Look Like: Real Examples
GitHub’s style is concise and action-oriented:
“Dependabot alerts now include the CVSS score and severity rating for each vulnerability, making it easier to prioritise remediation.”
Stripe’s style is precise and developer-focused:
“Added
confirmparameter toPaymentIntent.create. Whenconfirm=true, the intent is confirmed immediately, saving an extra API call for synchronous payment flows.”
Both examples share common traits:
- One clear sentence per change
- Specific, not vague (“easier to prioritise remediation”, not “improved”)
- Developer context included (why this change matters)
What to Avoid
Vague descriptions:
Poor: “Improved performance.” Better: “Reduced average response time for the
/searchendpoint from 420 ms to 85 ms under typical query loads.”
Developer jargon without explanation:
Poor: “Refactored the connection pool to use epoll.” Better: “Improved connection handling under high concurrency — the server now handles 3x more simultaneous connections before performance degrades.”
Missing migration information for breaking changes:
Poor: “Removed the legacy authentication method.” Better: “Removed the legacy
api_keyquery parameter authentication method. Migrate toAuthorization: Bearer <token>header authentication. See the [migration guide] for details.”
Practical Phrases for Release Notes
- “This release contains a breaking change to…”
- “Developers using X should update to Y before upgrading.”
- “This feature was deprecated in v2.1 and has now been removed.”
- “Fixed an issue where… which caused… under…”
- “Added support for… previously it was necessary to…”
- “No action is required for existing integrations.”
- “This change is backwards compatible.”
Good release notes are a form of respect for your users. They demonstrate that you understand the impact of your changes on real codebases and that you value your developers’ time. Invest in writing them well — they reduce support tickets, reduce upgrade friction, and build the kind of developer trust that drives long-term adoption.