Changelog template in Markdown, with a filled-in example
A CHANGELOG.md is the file in your repository that lists what changed in each version, newest first. This page gives you a template you can copy, the same template filled in so you can see what good entries look like, and the handful of mistakes that make a changelog useless. The layout follows Keep a Changelog 1.1.0 (keepachangelog.com), which is the most widely copied convention.
Copy this template
# Changelog
All notable changes to this project are listed here.
The format follows Keep a Changelog 1.1.0, and versions follow Semantic Versioning.
## [Unreleased]
### Added
-
## [1.0.0] - 2026-10-15
### Added
-
### Changed
-
### Deprecated
-
### Removed
-
### Fixed
-
### Security
-
[Unreleased]: https://example.com/your-repo/compare/v1.0.0...HEAD
[1.0.0]: https://example.com/your-repo/releases/tag/v1.0.0
Delete the headings you do not use in a release. An empty "Security" heading tells the reader nothing, and a missing one tells them nothing was fixed there.
What each heading means
| Heading | Put here |
|---|---|
| Added | New features a reader could start using. |
| Changed | Behaviour that already existed and now works differently. If an old script will break, say so and give the replacement. |
| Deprecated | Things that still work but will be removed. Name the version or date they go. |
| Removed | Things that no longer exist. |
| Fixed | Bugs, described by what the reader saw, not by the code you touched. |
| Security | Vulnerabilities fixed. Say which versions were affected so people know whether to upgrade. |
The same template, filled in
This is an invented example for a small command-line tool called tidy. It is here to show the style, not a real project.
## [Unreleased]
### Added
- `tidy --dry-run` prints what would be renamed without touching any file.
## [2.1.0] - 2026-09-30
### Added
- `tidy` reads a `.tidyrc` file in the current folder, so you no longer have to repeat flags.
### Changed
- Files are now sorted by name before renaming. Before, the order depended on the operating system, which gave different numbering on Linux and macOS.
### Deprecated
- The `--legacy-names` flag will be removed in 3.0.0. Use `--pattern` instead.
### Fixed
- Renaming a file whose name started with a dash no longer fails with "unknown option".
- A folder containing more than 10,000 files no longer runs out of memory.
## [2.0.0] - 2026-08-12
### Removed
- Node 16 is no longer supported. Use Node 18 or newer.
Notice what is and is not in there. Every line says what a person using the tool would see or have to do. Nothing says "refactor" or "bump dependencies", and nothing is a bare issue number. The breaking change in 2.0.0 names what to do about it.
Rules worth keeping
- Newest version first. People read the top of the file.
- Dates as YYYY-MM-DD. It sorts correctly and cannot be misread as day-month or month-day.
- Keep an Unreleased section at the top, and move its entries under the new version when you release.
- Write for people, not from commits. A list of commit messages answers a developer's question and few others'. Keep a Changelog says this directly: do not dump a git log into a changelog.
- Link each version to the comparison of its changes so a curious reader can see the code.
- If a release was pulled, keep it in the file and mark it
[YANKED]after the date, so nobody wonders where it went.
Changelog or release notes?
They overlap, and for a small project one file is enough. The difference shows up when more than one kind of person reads about your releases. A changelog in the Keep a Changelog layout is written for people who use the code and want the exact details. Customers of a product, and the people who support or sell it, usually want fewer words and different ones: what is new for them, and whom to tell. If that is you, write the notes once per audience. Our guide release notes for users, developers and your team shows the same change written three ways.
Check what you wrote
Three quick passes catch most of the damage:
- Search the file for
TODO,WIPandFIXMEbefore you release. - Look for lines that begin like a commit message (
fix:,chore:) and rewrite them as sentences. - Look for bare
#123numbers and bare web addresses, and say in words what the link leads to.
The free release notes checker does these checks in your browser: paste a section and it lists the lines to look at. Nothing is uploaded. If you want a command-line version for your repository, the checker's rules are also published as the open-source release-notes-lint tool.
When a single file is not enough
If you want a public page for your customers, a page for developers and feeds people can subscribe to, built from one Markdown file per release, that is what the Release Notes Kit does ($14, one purchase, no account). If a CHANGELOG.md is all you need, use the template above and ignore the rest.