Changelog examples: 8 changelogs for libraries, apps, APIs and docs

Eight annotated changelog examples: a Keep a Changelog CHANGELOG.md, a yanked release, a product updates page, an API with deprecations, patch notes and more.

By Strokes Team · · 16 min read

Key takeaways

  • A changelog lists the notable changes in every version, newest first, each version with its release date and its changes grouped as Added, Changed, Deprecated, Removed, Fixed and Security.
  • Semantic versioning ties the number to the entry: a MAJOR release has breaking changes to explain, a MINOR one adds features or deprecations, a PATCH one only fixes bugs.
  • Write each line for the person upgrading, not from the commit log, and never leave out a deprecation, a removal or a breaking change.
  • Keep a pulled release in the file marked [YANKED], and collect upcoming changes under Unreleased at the top.
A laptop on a sunlit desk open to a changelog, a list of releases down the left with the newest selected and its entries grouped under green, purple and red labels, beside a steaming mug of coffee, a stack of books, an open notebook with a fountain pen, a pencil cup and a pad of sticky notes.
Newest at the front, nothing thrown away. A changelog earns trust by being kept the same way every time.
Table of contents
  1. The Keep a Changelog format
  2. Semantic versioning in brief
  3. Open-source library CHANGELOG.md example
  4. Command-line tool with yanked release
  5. Web app product updates page
  6. Mobile app store changelog
  7. API changelog with deprecations
  8. Internal platform changelog
  9. Game patch notes example
  10. Style guide revision log
  11. Changelog vs release notes
  12. How to write changelog entries
  13. Building a changelog from commits
  14. Common changelog mistakes
  15. Frequently asked questions

A changelog is a file or page that lists the notable changes in each version of a project, newest first, with the release date of every version. Many projects follow the Keep a Changelog format, which groups each version's changes under six headings: Added, Changed, Deprecated, Removed, Fixed and Security. The eight changelog examples below cover different kinds of project, from an open-source library's CHANGELOG.md to a product updates page and an API changelog with shut-off dates, and each is followed by notes on why it works.

The projects are invented, so every entry can be copied and adapted. If you need the friendlier version of one release for users, with highlights and upgrade notes, start from the release notes template instead.

ExampleFormatBest for
ExampleOpen-source libraryFormatCHANGELOG.md in Keep a Changelog formatBest forPackages that follow semantic versioning
ExampleCommand-line toolFormatA yanked release and a security fixBest forTools people install and pin to a version
ExampleWeb appFormatDated product updates, no version numbersBest forProducts that ship every week
ExampleMobile appFormatStore “What's new” textBest forShort notes read on a phone
ExamplePublic APIFormatDated entries with breaking changes and shut-off datesBest forIntegrators who pin an API version
ExampleInternal platformFormatAction required, then everything elseBest forShared services other teams depend on
ExampleGameFormatPatch notes with old → new valuesBest forBalance changes players will argue about
ExampleStyle guideFormatRevision log per editionBest forHandbooks, style guides and SOP libraries
Pick the example closest to your project, then borrow its structure.

The Keep a Changelog format

Keep a Changelog, created and maintained by Olivier Lacan, is a short set of conventions for a CHANGELOG.md file. Version 1.1.0 defines a changelog as a curated, chronologically ordered list of notable changes for each version of a project. Its first principle is “Changelogs are for humans, not machines.” The others: every version gets an entry, changes of the same type are grouped, versions and sections can be linked to, the latest version comes first, each version shows its release date, and the file says whether the project follows semantic versioning.

HeadingUse it forExample line
HeadingAddedUse it forNew featuresExample line--cover option to set the cover image
HeadingChangedUse it forChanges to existing behaviorExample lineChapters are ordered by the number in the file name
HeadingDeprecatedUse it forFeatures that will be removed laterExample linebook.toml still works and will be removed in 3.0.0
HeadingRemovedUse it forFeatures removed in this versionExample lineEPUB 2 output
HeadingFixedUse it forBug fixesExample lineFootnotes in block quotes keep their back-links
HeadingSecurityUse it forFixes for vulnerabilitiesExample lineThe verbose log no longer prints access keys
The six types of change in Keep a Changelog 1.1.0. Leave out any heading a version doesn't need.

Three more conventions do most of the work. An Unreleased section at the top collects changes as they are merged, so a release only needs a new heading. Dates are written YYYY-MM-DD, which can't be misread the way 04/05/2026 can. And a yanked release, one pulled for a serious bug or security problem, stays in the file with [YANKED] after its date. The file is called CHANGELOG.md; Keep a Changelog notes that some projects use HISTORY, NEWS or RELEASES, and argues for one consistent name so people can find it.

Semantic versioning in brief

Semantic Versioning 2.0.0, originally written by Tom Preston-Werner, gives each part of a MAJOR.MINOR.PATCH number a meaning, so the number alone tells readers how careful to be with an upgrade.

ReleaseIncrement it when youThe entry should show
ReleaseMAJOR: 2.4.0 → 3.0.0Increment it when youMake incompatible API changesThe entry should showEvery breaking change, first, with what to do about it
ReleaseMINOR: 2.3.1 → 2.4.0Increment it when youAdd functionality in a backward-compatible wayThe entry should showWhat's new, plus anything deprecated and when it goes
ReleasePATCH: 2.3.0 → 2.3.1Increment it when youMake backward-compatible bug fixesThe entry should showThe fixes, and nothing a user has to change
  • 0.y.z is for initial development. Anything may change at any time, and 1.0.0 defines the public API. Flag breaking changes in a 0.x changelog anyway.
  • Pre-releases and builds have their own marks. A hyphen starts a pre-release label (1.0.0-alpha) and a plus sign starts build metadata (1.0.0+20130313144700).
  • “v1.2.3” is a tag name. The semantic version is 1.2.3, so write version headings without the v.
  • A released version never changes. If a minor release broke compatibility by mistake, SemVer's FAQ says to fix it in a new minor release that restores compatibility, and the changelog should say so.

Open-source library CHANGELOG.md example

A library's readers are developers deciding whether an upgrade is safe. Here is a complete CHANGELOG.md for mdbinder, an invented tool that turns a folder of Markdown chapters into an EPUB file.

CHANGELOG.md (an invented library, Keep a Changelog format)

# Changelog

All notable changes to mdbinder are documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added
- `--cover` option to set the cover image from the command line.

## [3.0.0] - 2026-10-02

### Removed
- **Breaking:** EPUB 2 output. mdbinder now writes EPUB 3 only. If you
  need EPUB 2, stay on 2.x, which gets security fixes until 2027-04-01.
- **Breaking:** the `book.toml` config file, deprecated in 2.4.0.
  Run `mdbinder migrate-config` to convert it to `book.yaml`.

### Changed
- Chapters are ordered by the number at the start of the file name
  (`01-arrival.md`), not alphabetically. Files without a number go last.

### Fixed
- Footnotes inside block quotes keep their back-links (#214).

## [2.4.0] - 2026-07-15

### Added
- `toc_depth` setting in `book.yaml` for the table of contents.

### Deprecated
- `book.toml`. It still works in 2.x and will be removed in 3.0.0.

## [2.3.1] - 2026-06-03

### Fixed
- Curly quotes in chapter titles are no longer straightened in the
  table of contents (#198).

[unreleased]: https://example.com/mdbinder/compare/v3.0.0...HEAD
[3.0.0]: https://example.com/mdbinder/compare/v2.4.0...v3.0.0
[2.4.0]: https://example.com/mdbinder/compare/v2.3.1...v2.4.0
[2.3.1]: https://example.com/mdbinder/compare/v2.3.0...v2.3.1

Why it works. The header says which format and which versioning scheme the file follows, as Keep a Changelog asks. The 3.0.0 entry leads with its two breaking changes and says what to do about each, and the config file was deprecated one minor version earlier, in 2.4.0, the order SemVer's FAQ recommends. Issue numbers stay because these readers will click them, and the link references at the bottom turn every version heading into a link to its diff.

Command-line tool with yanked release

A tool people pin to a version needs the uncomfortable entries most: the release that was pulled and the security fix that replaced it.

CHANGELOG.md for snapkeep, as rendered on the repository page

[1.9.1] - 2026-09-18

Security

  • The --verbose log no longer prints the storage access key. If you ran 1.9.0 with --verbose, rotate that key and delete the old logs. Advisory SK-2026-03.

Fixed

  • Restores no longer stop at the first file with a non-ASCII name (#341).

[1.9.0] - 2026-09-10 [YANKED]

Pulled on 2026-09-12 because --verbose wrote access keys to the log. Use 1.9.1.

Added

  • --exclude-from FILE reads exclusion patterns from a file, one per line.

Changed

  • The default compression level is now 6 (was 3). Backups are smaller and take longer to write; pass --level 3 for the old speed.
Original example, written for this guide. snapkeep is an invented backup tool.

Why it works. The yanked version stays in the file, marked the way Keep a Changelog recommends, with the reason and the version to use instead, so anyone who pinned 1.9.0 can see why it is no longer offered. Security comes first in 1.9.1 and tells readers what to do, not only what changed. The Changed line names the cost of the new default and how to opt out.

Web app product updates page

Nobody installs a version of a web app, so a product changelog is organized by date. Its readers are customers, not developers.

Product updates page for Quotebook, an interview transcription app

Speaker names carry over · November 4, 2026

Name a speaker once and Quotebook suggests the same name in your later interviews with that person. You confirm each suggestion. Read more: How speaker names work.

  • Improved: Word exports keep timestamps in their own column, so you can sort quotes by time.
  • Fixed: Search no longer finds words in interviews you deleted.

Fixes · October 21, 2026

  • Fixed: Uploads over 2 GB no longer fail at 99 percent on slow connections.

Share a highlight · October 7, 2026

Select a passage in a transcript and choose Share highlight to send a link to that passage with its audio. Links expire after 30 days; change that in Settings › Sharing.

Original example, written for this guide. Quotebook is an invented product.

Why it works. Each headline names the change and the date follows it, because readers scan the page for what is new, not for a day. Each entry starts with what the reader can now do and points to the help article. The quiet fortnight still gets its one line, which tells customers the product is looked after. And “You confirm each suggestion” answers the question a journalist would ask before trusting the feature with a source's name.

Mobile app store changelog

Store notes are read in a list of other updates, on a small screen. Three lines are plenty.

App store “What's new” text for Tidewatch 4.2
  • Tide alerts: get a notification an hour before high water at any saved harbor. Turn them on in Settings › Alerts.
  • Wind arrows now show gusts as well as average speed.
  • Fixed: the home screen widget no longer shows yesterday's tides after midnight.
Original example, written for this guide. Tidewatch is an invented tide-table app.

Why it works. The change most people will notice comes first and says where to find it. The text doesn't open with “What's new in 4.2”: the store already shows the version number, and the first line is the one a reader sees before deciding to read on. There is no “bug fixes and performance improvements” line, which tells the reader nothing. The full changelog on the app's website, under the same version number, carries the detail.

API changelog with deprecations

Integrators read an API changelog to answer one question: will my code break, and when? Every entry says which versions it affects.

API changelog for Innkeep, a hotel booking API

2026-11-02 · New API version 2026-11-02

These changes apply only when you request version 2026-11-02. Integrations pinned to an earlier version see no change.

  • Breaking: GET /v1/reservations returns 50 results per page by default (was 100). Pass limit=100 to keep the old page size.
  • Added: cancellation_deadline on the Reservation object, as an ISO 8601 date and time.

2026-10-19 · All versions

  • Deprecated: POST /v1/rates/bulk. Use POST /v1/rate_jobs, which returns a job ID you can poll. The old endpoint stops responding on 2027-05-03, and its responses now carry Deprecation and Sunset headers. Migration guide: Bulk rate updates.
  • Fixed: 422 errors for an invalid check-in date name the field in error.param.
Original example, written for this guide. Innkeep is an invented API.

Why it works. The breaking change says exactly what to send to keep the old behavior. The deprecation names the replacement, the shut-off date and the migration guide, and the API repeats the warning in its responses: the Deprecation header (RFC 9745, March 2025) marks a resource as deprecated, and the Sunset header (RFC 8594, May 2019) gives the date it is expected to stop responding. Several public APIs name versions by date. Stripe's sample requests send a Stripe-Version header that starts with a date, and GitHub's send an X-GitHub-Api-Version date. The technical writing examples show how the rest of a developer docs set fits around it.

Internal platform changelog

Inside a company, the readers are other engineering teams, and they want to know whether they have to do anything.

Weekly changelog from a build platform team

Week of 2026-10-19

Action required by 2026-11-16

  • The node18 build image is retired on 2026-11-16. Change image: node18 to image: node22 in .ci.yml. Still on node18: payments-web and search-indexer (owners emailed on 2026-10-20).

No action needed

  • Branches of the same repository now share a build cache. Median build time on main fell from 9 min 40 s to 6 min 5 s.
  • Test reports over 10 MB are no longer cut off in the build summary.

Questions: #build-platform. Next entry: 2026-10-26.

Original example, written for this guide. The teams and figures are invented.

Why it works. The split answers the reader's only question before any detail. The action has a date, the exact line to change and the names of the teams still affected. The improvement comes with a before-and-after number instead of an adjective.

Game patch notes example

Patch notes are a changelog for an audience that reads every number. Balance changes show the old value and the new one.

Patch notes for Lanternfall 1.6.0

The Harbor Update · Patch 1.6.0 · 2026-11-05

New

  • The Saltmarsh harbor district, with four new quests and the Ferryman's shop.

Balance

  • Longbow damage 42 → 38. Draw time 0.9 s → 0.8 s.
  • Healing tonic cooldown 20 s → 30 s.

Designer's note: the longbow was the best weapon at every range. It should win at long range and lose up close. The faster draw keeps it fun to use.

Fixed

  • Saving during the bell tower cutscene no longer locks the camera when you load the game.

Known issues

  • Controller vibration doesn't work in Saltmarsh. A fix is planned for 1.6.1.
Original example, written for this guide. Lanternfall is an invented game.

Why it works. Old → new values let players judge each change for themselves. The designer's note gives the reason for the most disputed change, which players would otherwise guess at. Known issues come with the planned fix, so nobody reports them again.

Style guide revision log

Documents change too. A style guide needs a changelog more than most, because editors apply its rules from memory and need to know when one moved.

Revision log for a newsroom style guide

Edition 5.2 · 2026-09-01

Changed

  • Percent: use the % sign with figures in all copy (was: “percent” in body text, % only in tables and charts).
  • Headlines: sentence case in every section. Sports moves over from title case.

Added

  • Entry: livestream, one word, as a noun and a verb.

Removed

  • The rule against starting a sentence with “But”. It was never enforced.

Applies to copy filed from 2026-09-01. Archive stories are not updated.

Original example, written for this guide. The newsroom and its rules are invented.

Why it works. Each change records the old rule as well as the new one, so a copy editor can tell an older story from a mistake. The last line says when the edition takes effect and that the archive stays as it is. The same log works for an SOP library (see the SOP examples, each of which ends with a revision line) and for a book's style sheet.

Changelog vs release notes

The two often start from the same change, but they serve different readers. Here is the widget fix from the Tidewatch store text above, written once for each:

In CHANGELOG.md, for developersIn the release notes, for users
The lineIn CHANGELOG.md, for developersFixed: the widget timeline reloads at local midnight instead of at the next app launch (#412).In the release notes, for usersFixed: the home screen widget no longer shows yesterday's tides after midnight.
It tells the readerIn CHANGELOG.md, for developersWhat the code now does, and where the discussion isIn the release notes, for usersWhat they saw go wrong, in their words
It leaves outIn CHANGELOG.md, for developersHow the bug looked on a phoneIn the release notes, for usersThe mechanism and the issue number

Put the issue number in the store text and no user can do anything with it. Leave the mechanism out of the changelog and the next developer can't tell what changed, or whether a later bug is the same one coming back. Keep one source of changes and write both versions from it, so the two never disagree about what shipped.

ChangelogRelease notes
ReaderChangelogDevelopers, integrators, anyone upgradingRelease notesUsers and customers, support and sales
CoversChangelogEvery notable change in every versionRelease notesOne release, the changes people will notice
ShapeChangelogTerse lines grouped by typeRelease notesHighlights first, then short lists and upgrade steps
Lives inChangelogCHANGELOG.md, a changelog page, the API docsRelease notesRelease emails, in-app notices, store pages, a blog
Kept forChangelogAs long as the project existsRelease notesThe weeks around the release

How to write changelog entries

  • Start from what changed for the reader. Use the names on the screen or in the API, not the names of internal modules.
  • One change per line, breaking changes first. Mark them “Breaking” even under Removed or Changed, so readers scanning for the word find it.
  • Say what to do. A deprecation names its replacement and its removal version or date. A breaking change gives the migration step or links to it.
  • Use numbers instead of adjectives. “Builds take 6 minutes instead of 10” beats “much faster builds”.
  • Write the entry when the change merges. Add a line under Unreleased in the same pull request. Reconstructing a month of changes on release day is when entries go missing.

Tells the reader what changed

  • Search results load in under a second for libraries of 10,000 notes (was about 4 seconds)
  • Removed: the /v1/export endpoint. Use /v2/exports; see the migration guide
  • Dates in CSV exports use YYYY-MM-DD in every language setting
  • Security: session cookies are now marked Secure and HttpOnly

Tells the reader nothing

  • Bug fixes and performance improvements
  • Various improvements to export
  • Refactored session handling
  • Updated dependencies

If you keep the changelog in Strokes, ask the Strokes Assistant to review a new entry against the rest of the file. It flags inconsistencies such as a version without a date, a breaking change filed under Fixed or a deprecation with no removal date.

Building a changelog from commits

Conventional Commits 1.0.0 calls itself “a lightweight convention on top of commit messages”. Each message starts with a type: fix commits map to PATCH releases, feat commits to MINOR releases, and a BREAKING CHANGE footer or a ! after the type to MAJOR. Its site lists automatic changelogs among the reasons to adopt it, and release tools can turn such a history into a sorted draft.

Five of the commits merged between 2.4.0 and 3.0.0

feat!: drop EPUB 2 output
fix: keep footnote back-links inside block quotes (#214)
refactor: split the parser into two modules
chore(deps): bump yaml to 2.6.1
feat!: remove support for book.toml

From those five commits, three lines reach the 3.0.0 entry in the file above: two breaking entries under Removed (EPUB 2 and book.toml) and one under Fixed (the footnotes). The ! marks are also what make the next version 3.0.0. The refactor and the dependency bump disappear, because nothing changed for the reader. That editing step is the point. Keep a Changelog's warning still holds: commit logs are full of noise, because a commit records a step in the work, while a changelog entry records a difference someone will notice.

Common changelog mistakes

  • Leaving out the awkward parts. Keep a Changelog warns that a changelog mentioning only some changes can be as dangerous as none. Deprecations, removals and breaking changes are the lines people most need.
  • Dates people can misread. 04/05/2026 is April in the US and May in most of Europe. Use 2026-04-05.
  • Deleting a bad release. Mark it [YANKED], say why and point to the replacement.
  • A version number that contradicts the entry. A “Breaking” line under a PATCH release tells users the number can't be trusted.
  • Internal shorthand in a public changelog. Code names and team names mean nothing to customers.

Frequently asked questions

Do I need semantic versioning to keep a changelog?

No. A changelog works with any versioning scheme, including dates or plain release numbers, and a web app can use dates alone. Semantic versioning helps because the number itself signals risk: a new MAJOR version means breaking changes, which the changelog then explains. Whatever you use, say so at the top of the file.

Does marking a release [YANKED] remove it?

No. In a Keep a Changelog file the mark only tells readers. To stop new installs, yank the version in the package registry as well. On PyPI, installers skip a yanked release unless a project pins exactly that version, and Cargo won't pick a yanked crate version for a project without an existing lockfile. Neither registry deletes the files.

Should a changelog list refactors and dependency updates?

Not in a public changelog, unless the reader feels the effect. A refactor that changes nothing for users stays in the commit history. A dependency bump earns a line when it fixes a vulnerability, raises a minimum version or changes behavior. An internal platform changelog can be broader, because other teams do feel a new build image.

Read next