River
Y CombinatorBacked by Y Combinator

Software & TechnicalFree tool

Release Notes Generated From Commits

Release notes written from your commits: grouped by what changed for your readers, breaking changes first, and every commit accounted for.

Helpful to include

Free to start · Opens in your River workspace, ready to edit and share

How to write release notes from commits

Release notes tell the people who use your software what changed in a release and whether they need to do anything about it. Writing them from commits means collecting every commit since the last release, grouping those that make one change, and describing each change in your reader's words. Good notes lead with breaking changes and the action each one needs, and they leave out work nobody outside the team can see.

Keep a Changelog, a convention maintained by Olivier Lacan, draws the line that matters most. A commit documents "a step in the evolution of the source code"1, while a changelog entry documents "the noteworthy difference, often across multiple commits." Your notes describe the difference, not the steps.

A screen showing a Git commit graph with messages labeled feat, fix, perf, refactor, test and chore beside a version tag
Read the whole range, including the refactors and chores tools hide. Photo: Yancy Min on Unsplash

Collect every change in the release

Work from the full list of commits between the last release and this one, not from memory. Memory keeps the headline features and drops the one-line change that breaks someone's integration.

  1. Fix the range

    Start at the last release's tag and end at the commit you're shipping. Every commit in between gets a decision: in a note, or left out on purpose.

  2. Add pull requests and tickets

    Commit messages say what changed in the code. Pull request descriptions and linked tickets usually say why, and who asked for it.

  3. Treat a generated list as a draft

    GitHub can draft notes for a release2 that list its merged pull requests, its contributors and a link to the full changelog. Its own instructions say to check they include "all (and only)" what you want.

  4. Read what your tools hide

    The Conventional Commits preset for conventional-changelog hides docs, style, chore, refactor, test, build and ci commits by default3 unless they're marked as breaking. Skim them anyway. A refactor can change behavior, and a dependency bump can cross a major version.

  5. Net out reverts

    A feature added and then reverted inside the range never reached anyone, so it needs no note.

Group commits into changes users notice

Sort the list by what a reader would notice. Kubernetes' contributor guide says any user-visible or operator-visible change qualifies for a release note4. Its examples include API, command-line, UI and configuration changes, changes in behavior or efficiency, deprecations and security fixes. Tests, build infrastructure and fixes for bugs that never shipped need none.

Then merge the commits that make one change. A feature often lands as the interface, the API and a fix found in review. Readers see one change, so write one note and record which commits it covers.

One release, sorted: seven commits become three notes

CommitTypeWhere it goes
Add resource picker to bookingsfeatAdded: book several resources at once
Accept resource_ids in the bookings APIfeatSame note, with a line for developers
Fix clash check for a second resourcefixSame note: the bug never shipped
Drop legacy fuzzy option from search APIrefactorBreaking: fuzzy search removed
Stop CSV export cutting off at 10,000 rowsfixFixed: large exports are complete
Cover multi-resource bookings in teststestLeft out: no visible effect
Cache dependencies in CIchoreLeft out: internal only

An illustrative release written for this guide.

Find every breaking change

A breaking change makes a reader's existing code, settings or habits stop working, or work differently. Conventional Commits flags one with a ! after the type or a BREAKING CHANGE footer, and it can appear in a commit of any type5. As the spec itself notes, a commit that skips the format "will be missed by tools that are based on the spec," so check the changes themselves.

Google's API design guidance, AIP-180, treats removing or renaming a field, adding a required field, changing a field's type and changing a default value6 as breaking. It also warns that code often depends on behavior you never documented. Whatever a commit's type, check it for:

  • A field, endpoint, option or setting removed or renamed
  • A new required input, or an optional one made required
  • A changed type, format, unit or time zone in a value
  • A changed default, sort order or error code
  • A migration or setting that must run before the deploy
  • A dependency bumped across a major version

Silent breaks are the worst kind

A removed field fails loudly, so someone notices on day one. A changed default or time zone keeps working and quietly returns different results. Put these first and tell readers how to check.

Warn before you remove anything. Semantic Versioning asks for at least one minor release that contains the deprecation7 before the removal ships in a major one. Keep a Changelog adds that readers should be able to upgrade, remove what's deprecated, then upgrade to the version that removes it1.

If a change needs a data migration or a staged switch, plan the steps and the rollback in a technical migration plan before you write the note.

Write each release note for its reader

Order the notes by what readers must act on: breaking changes and required actions, then deprecations, changes to existing behavior, new features and fixes. Keep a Changelog's six change types make clear headings: Added, Changed, Deprecated, Removed, Fixed and Security1.

Write each entry as the effect, then the action. Kubernetes asks authors to write in the past tense and add a call to action, with a link, when users must do something4. It also reminds them that most users don't know the technical details of a change.

Match the words to the reader. Developers need exact field names, endpoints and error codes; end users need the benefit in plain words, never a function name. When an API changes, update its reference in the same release. An API documentation template keeps endpoint pages, errors and a dated changelog together.

ExampleThe same release, written upAn illustrative example written for this guide

Breaking: Removed the fuzzy option from search. Searches that still use it, including saved ones, now return exact matches only. Check any your team relies on.

Added: Bookings can now hold several resources, such as a room and a projector, and each one is checked for clashes. In the API, send resource_ids when you create a booking.

Fixed: Exports with more than 10,000 rows now include every row.

  • Breaking change first. The one change that can hurt a reader leads, with what to do about it.
  • One note per change. Three commits became one entry about booking several resources.
  • Symptoms, not code. The fix names the problem people saw, so they recognize it.

Set the version number and publish

Let the biggest change set the version number. Under Semantic Versioning7, an incompatible API change means a new major version, backward compatible features a minor one, and backward compatible bug fixes a patch. By that rule, the removed search option makes the example a major release, even though its commit said refactor.

Date each release in year-month-day form, such as 2026-10-29, so no reader confuses the day and month. Then publish where readers already look: the changelog file, the release page and an in-app message. Email anything that needs action ahead of time.

Before you publish release notes

  • Every commit is in a note or left out on purpose
  • Breaking changes come first, each with the action to take
  • Deprecations name the replacement and when removal comes
  • Each entry says what changed for the reader, not in the code
  • No function names or ticket numbers in notes for end users
  • The version number matches the biggest change
  • The release has a date and a link to the full changelog

The tool at the top of this page does the first pass for you. It groups your commits into changes readers notice, puts breaking changes first and accounts for every commit. To plan the email, in-app message and changelog entry for each release, start from the release notes and changelog template.

How it works

Start with what went into the release: paste or attach the commit list, merged pull requests, a ticket export or the diffs. If the code is on GitHub, name the repository and the two versions, and River offers to connect it so it can read the changes directly. Pick who will read the notes, and River groups the commits into the changes those readers will notice.

It reads the refactors, chores and dependency bumps that generators hide, and when it can see the code, it trusts the change over the commit message. It never invents a change, version or date. Anything unclear becomes an open question, and a sheet maps every commit to the note it fed or the reason it was left out.

  1. Share the changes

    Paste or attach the commits, pull requests or tickets, or name the GitHub repository and versions.

  2. River groups the commits

    It reads every commit, including the ones generators hide, and groups them into changes readers notice.

  3. Get your release notes

    Breaking changes and actions first, then deprecations, changes, new features and fixes, plus a sheet tracing every commit.

  4. Edit and publish

    Answer its open questions, adjust the wording, then ask for a customer email or an upgrade guide.

What you get

  • Release notes grouped by the change a reader notices, not one line for every commit
  • Breaking changes and required actions at the top, each saying exactly what the reader must do
  • A change register sheet mapping each commit to its note, or the reason it was left out
  • Refactors, chores and dependency bumps checked too, so a behavior change hidden in one still gets a note
  • Wording matched to the readers you pick, from field names for developers to plain benefits for users
  • A suggested version number and a short list of open questions where a commit's effect is unclear

Common questions

What is the difference between release notes and a changelog?

A changelog is the running record of notable changes in every version, usually kept as one file with the newest version first. Release notes cover one release, written for a particular audience, and should lead with anything readers must act on. Many teams use the two terms interchangeably. What matters is that neither one is a raw list of commits.

How do I write release notes from commits with River?

Paste or attach the commits, merged pull requests or a ticket export in the box at the top of this page, and choose who will read the notes. River groups the commits into changes a reader would notice and puts breaking changes first. The notes and a register of every commit open in your free River workspace.

Can I generate release notes from commits automatically?

Yes, as a first draft. GitHub can list a release's merged pull requests and contributors, and conventional-changelog sorts typed commits into sections such as Features and Bug Fixes. Neither merges related entries, catches a breaking change nobody marked or rewrites a developer's wording for customers. That part still needs a careful read of the changes themselves.

What counts as a breaking change?

Any change that makes a reader's existing code, settings or workflow fail, or behave differently, as soon as they upgrade. Common examples are a removed or renamed field, a new required input, a changed type or format, and a changed default. The quiet ones, where nothing errors but results change, are the most dangerous, so list those first.

How long should release notes be?

Release notes usually need one or two sentences per change: one on what changed and, when readers must act, one on what to do. Cover every change a reader needs to know about and nothing else. Merging related commits and leaving out internal work is what keeps even a large release short enough to read.

Does it pick the version number?

It suggests one and leaves the decision to you. Following Semantic Versioning, anything breaking points to a major version, new features to a minor one and fixes alone to a patch. If a commit's type and its actual effect disagree, such as a refactor that removes an option, the suggestion follows the effect.

Is the release notes generator free?

Yes, it is free to start. Your release notes and commit register open in a River workspace, where you can edit them, share them or ask River to change them. Paid plans add more AI use and access to the most advanced models.

Sources

  1. keepachangelog.com. “Keep a Changelog.” keepachangelog.com (opens in a new tab)

  2. GitHub Docs. “Automatically generated release notes.” docs.github.com (opens in a new tab)

  3. Conventional Changelog. “Introduction.” conventional-changelog.js.org (opens in a new tab)

  4. Kubernetes Contributors. “Adding Release Notes.” kubernetes.dev (opens in a new tab)

  5. Conventional Commits. “Conventional Commits 1.0.0.” conventionalcommits.org (opens in a new tab)

  6. Google API Improvement Proposals. “AIP-180: Backwards compatibility.” google.aip.dev (opens in a new tab)

  7. Semantic Versioning. “Semantic Versioning 2.0.0.” semver.org (opens in a new tab)

Built by

Chandler Supple

Co-founder & CEO, River

Chandler has spent the last six years working in AI, building tools for millions of users and Fortune 100 companies. In 2025, he co-founded River to build a new kind of operating system for AI agents.

Reviewed by

Brian Joseff, Co-founder, River