Keep a Changelog has been the default answer to “how should I write a CHANGELOG.md?” for over a decade. Last month it shipped version 2.0.0 — its first major revision since 2017 — and took a firm position on the biggest question facing changelogs in 2026: what happens when machines both write and read them. Here’s the full format, what changed, and an honest look at when to outgrow it.
In 2014, Olivier Lacan — then at Code School — published a small site with a blunt tagline: “Don’t let your friends dump git logs into changelogs.” The idea was almost embarrassingly simple: a CHANGELOG.md file, newest release first, dated in ISO 8601, with changes grouped into a handful of fixed categories. No tooling, no vendor, no schema. Just a convention.
It worked. Keep a Changelog is now followed by tens of thousands of open-source projects (the project’s own count) — Tailwind CSS and StandardJS carry its canonical preamble, and Unity goes further, requiring the format for packages in its Asset Store validation docs, down to the exact six subsection names.
And on June 7, 2026, it got its first major revision in nine years. Version 2.0.0 retired the git-logs tagline for a calmer one — “Clearly document the evolution of your projects” — and, in the project’s own words, “breaks the guidance, not the format.” (One note if you go looking: as of this writing, the keepachangelog.com homepage still defaults to the 1.1.0 spec — 2.0.0 lives at keepachangelog.com/en/2.0.0/, and the release is recorded in the project’s own CHANGELOG.md.)
The Format in Two Minutes
A Keep a Changelog file looks like this:
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/),
and this project adheres to [Semantic Versioning](https://semver.org/).
## [Unreleased]
### Added
- Webhook retry configuration
## [1.4.0] - 2026-07-10
### Added
- PDF export for dashboards
### Changed
- Default session timeout raised from 30 to 60 minutes
### Deprecated
- `user.email` field; use `user.primary_email`
### Fixed
- Crash when importing empty CSV files
### Security
- CVE-2026-12345: patched XML parser vulnerability
## [1.3.1] - 2026-06-02 [YANKED]
The rules that make it work:
- One section per version, latest first, heading format
## [1.4.0] - 2026-07-10with the date in ISO 8601 — no ambiguous regional formats. - An
Unreleasedsection at the top tracks upcoming changes, so writing the changelog happens continuously instead of in a panic at release time. - Version headings are links — Markdown reference links pointing at compare URLs (
compare/v1.3.1...v1.4.0), so every section is a clickable diff. [YANKED]marks pulled releases — in the spec’s words, “the brackets make the tag easy to notice and easy to parse.”
The six change types
Every entry goes under exactly one of six headings, and the definitions are one line each:
| Type | Meaning |
|---|---|
Added |
New features |
Changed |
Changes in existing functionality |
Deprecated |
Soon-to-be removed features |
Removed |
Now removed features |
Fixed |
Bug fixes |
Security |
Vulnerabilities |
Version 2.0.0 adds useful disambiguation: when unsure between Changed and Fixed, ask whether the old behavior was a bug. Security entries should lead with the CVE ID. Dependency bumps are explicitly not a change type. And the spec refuses, permanently, to add a seventh category: “Keeping to the six leaves every changelog readable the same way, and parseable by the same tools.”
That refusal is the format’s whole personality. Six types, plain dates, one file. The constraint is the feature.
The Principles Behind It
The spec’s guiding principles are worth internalizing even if you never use the file format, because they describe good release communication anywhere:
- “Changelogs are for humans, not machines.” The founding principle, unchanged since 2014.
- There’s an entry for every single version — including the embarrassing ones. The spec’s anti-pattern list is direct about this: “A changelog which only mentions some of the changes can be as dangerous as not having a changelog.”
- If you do nothing else, list deprecations, removals, and breaking changes. Skipping a feature announcement disappoints people; skipping a removal breaks them.
- Never dump commit logs. “They’re full of noise” — the original sin the whole project was created to stop.
- New in 2.0.0: “Write plainly.” Many readers aren’t native speakers; favor clear, concise wording.
2.0.0 also relaxed the versioning rule: you no longer need Semantic Versioning specifically — calendar versions, plain numbers, or dates all qualify — you just have to say which scheme you use. (If you do use SemVer, the mapping is natural: Deprecated entries belong in a minor release, Removed in a major one. Our Conventional Commits guide covers how commit types drive those version bumps automatically.)
What 2.0.0 Says About AI — and Why It Matters
The most interesting part of the revision is a new section on automation and LLMs, because it stakes out a clear position on 2026’s central changelog tension.
On generation, the spec lands on a crisp rule: “machines can draft, but humans curate.” It acknowledges LLM-drafted changelogs directly — even suggesting you give a model “the brief you would give a contributor,” including via an AGENTS.md file — but holds the line on the output: “A generated changelog is raw material at best: a person still has to choose what is notable, group it, and write it for the reader.” That’s consistent with how the ecosystem’s own tools have evolved. git-cliff (which ships a Keep a Changelog template), Google’s release-please, and changesets all generate entries from commit history — and the spec names them while warning that “a commit and a changelog entry are written for different people, and one does not convert cleanly into the other.” (Notably, standard-version — for years the default generator — is now officially deprecated in favor of release-please.)
On machine consumption, the spec is even firmer: “There is no separate machine format, and there will not be one: this page is the format.” No JSON schema, no changelog.xml. The argument is that a consistently formatted Markdown file is already parseable — “a benefit of writing clearly, not a reason to write for machines.”
We’d gently push on that last point. It’s true that a disciplined CHANGELOG.md is the most machine-readable artifact most projects have — it’s exactly the kind of structured Markdown AI coding tools ingest well. But “for humans, not machines” was coined in 2014, and in 2026 a growing share of your changelog’s readers are AI agents answering questions about your product. The good news: the format’s own discipline — fixed categories, ISO dates, one entry per version — is precisely what makes it work for both audiences. Follow the spec and you get machine-readability for free, whatever the tagline says.
The Critics and the Variants
Keep a Changelog has been argued with for a decade, and the arguments are instructive.
Common Changelog (common-changelog.org) is the stricter fork: it adds commit/PR references, authors, and a **Breaking:** prefix, but drops the Deprecated and Security categories and removes the Unreleased section entirely, calling it “an unproductive workflow” (it’s a chronic merge-conflict site — the reason tools like towncrier exist, building the changelog from per-change fragment files instead). It also calls Conventional Commits an antipattern that “adds cognitive overhead by injecting itself into the middle of a workflow,” and warns against full automation: “This results in poor changelogs, defeating their purpose.”
The anti-generator argument got a fresh airing in 2026 when a widely discussed post argued Conventional Commits focuses teams on the wrong things. Lacan himself turned up in the Hacker News thread, and his comment is a neat summary of his project’s stance: “I’ve always had a stance with KAC that folks trying to automate changelog creation (prior to LLM rise, mind you) were focusing on the wrong thing.”
The GitHub Releases question. Plenty of major projects — Next.js, Bun — skip CHANGELOG.md entirely and publish through GitHub Releases or blog posts. The spec’s counterargument has been there since 1.1.0: GitHub Releases “create a non-portable changelog that can only be displayed to users within the context of GitHub.” Your changelog goes where your code goes; what a host generates for you does not.
When You Outgrow the File
Here’s the pattern worth noticing: the most-used developer products don’t stop at a CHANGELOG.md — they publish a changelog page. VS Code has no CHANGELOG.md in its repo at all; its release notes live at code.visualstudio.com/updates. Linear, Vercel, Raycast, Cursor, Supabase, Sentry, and GitHub itself all maintain hosted changelogs.
The reason isn’t fashion. It’s audience. A repo file serves people who read your repository — contributors, integrators, packagers. The moment your changelog’s readers include product users, three needs appear that a file in git can’t meet:
- A URL you can send people to — from support conversations, in-app notifications, and emails. (Changelog vs release notes is the same distinction the 2.0.0 spec now draws: “The changelog is the source; release notes are drawn from it.”)
- Distribution — an in-app widget, email subscriptions, RSS. A CHANGELOG.md is pull-only; nobody refreshes your repo to see what shipped.
- A stable, crawlable surface for search engines and AI assistants — dated entries at persistent URLs that rank and get cited.
The spec would (fairly) note the trade-off: a hosted changelog lives in someone’s database, not your repository. The pragmatic answer is both — keep the repo file if contributors need it, and treat a hosted changelog as the user-facing publication layer. That’s the model ReleasePad is built around: drafts generated from your GitHub commits, curated by a human (the spec’s “machines draft, humans curate,” operationalized), published to a hosted page, a widget, and a Markdown feed AI tools can read.
The Bottom Line
Use the format. Even if you adopt none of the tooling and never host a changelog page, the six categories, ISO dates, and the deprecations-above-all rule will make your release communication better — the spec is a decade of accumulated good judgment in a ten-minute read, and the 2.0.0 revision kept every part that mattered.
Then be honest about your audience. If it’s contributors, the file is enough. If it’s users — human or AI — the file is your source of truth, not your publication. Write it once, in this format, and let it feed everything else: your release notes, your widget, your feeds.
Further Reading
Frequently Asked Questions
What is the Keep a Changelog format?
Keep a Changelog is a convention for writing a CHANGELOG.md file, created by Olivier Lacan in 2014. Each release gets its own section with an ISO 8601 date (like ## [1.2.0] - 2026-07-10), newest first, with changes grouped under six categories: Added, Changed, Deprecated, Removed, Fixed, and Security. An Unreleased section at the top tracks upcoming changes.
What are the six change types in Keep a Changelog?
Added for new features, Changed for changes in existing functionality, Deprecated for soon-to-be removed features, Removed for now removed features, Fixed for bug fixes, and Security for vulnerabilities. The spec deliberately refuses to add more — version 2.0.0 states that keeping to six leaves every changelog readable the same way and parseable by the same tools.
What changed in Keep a Changelog 2.0.0?
Version 2.0.0, published June 7, 2026, is the first major revision since 1.0.0 in 2017. It breaks the guidance, not the format: the six change types, ISO dates, and Unreleased section are unchanged. New material covers LLM-drafted changelogs (machines can draft, humans curate), Conventional Commits, monorepos, CI/CD, and non-SemVer versioning. The old tagline about git logs was replaced with 'Clearly document the evolution of your projects.'
Does Keep a Changelog require Semantic Versioning?
Not anymore. The 1.x spec said to mention whether you follow Semantic Versioning; 2.0.0 loosens this to 'note which versioning scheme you use' — calendar versioning, a plain number, or a date all work. SemVer still pairs naturally with the format, since Deprecated entries map to minor releases and Removed entries to major ones.
Can I generate a Keep a Changelog file automatically?
Partially. Tools like git-cliff (which ships a Keep a Changelog template), release-please, and changesets can generate changelog entries from commit history. But the spec itself warns that a commit and a changelog entry are written for different people, and calls generated changelogs 'raw material at best' — a person still has to choose what's notable and write it for the reader.
When should a team move beyond a CHANGELOG.md file?
When your audience stops being people who read your repository. VS Code, Linear, Vercel, Cursor, and GitHub itself all publish hosted changelog pages rather than (or in addition to) a repo file, because product users, customer success teams, and AI assistants need a URL, not a file in git. The honest trade-off: a hosted changelog adds distribution and analytics; the repo file stays portable and vendor-free.
Ready to put this into practice?
Your changelog shouldn't be an afterthought.
ReleasePad makes it easy to publish great release notes — from a public changelog page to an in-app widget, GitHub integration, and analytics. Free to get started.
Get started — it's free