Skip to main content
Template • 5 sections

Product Changelog Template for Engineering Teams (2026)

A well-maintained changelog is one of the most underrated engineering assets. It tells users what changed and why, helps developers understand release history, satisfies compliance requirements, and keeps support teams informed without Slack DMs. The industry standard format comes from keepachangelog.com: every version gets a dated entry with changes grouped into Added, Changed, Deprecated, Removed, Fixed, and Security. This template covers the full format — from a rolling Unreleased section to version entries, plus variations for public product changelogs and internal technical release notes.

2-minute setup • No credit card required

When to use this template

Maintain this document in your repository root as CHANGELOG.md, updated with every pull request that ships user-facing or API-breaking changes. Generate entries automatically from conventional commits or use Gitmore to pull the week's merged PRs into a draft you refine before release.

5 sections

Template Variations

Pick the format that fits your context.

Changelog File Header

The header sets expectations: what format is used, how versions are numbered, and where to find older entries. Readers need this context once — put it at the top of your CHANGELOG.md and never change it.

Template
# Changelog

All notable changes to [Product Name] are documented in this file.

The format follows [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).

**Version types:**
- `MAJOR` (X.0.0) — Breaking changes, incompatible API changes
- `MINOR` (1.X.0) — New features, backwards-compatible
- `PATCH` (1.0.X) — Bug fixes, backwards-compatible

---
Replace [Product Name] with your actual product or repository nameKeep the semver link — it signals to contributors that you take versioning seriouslyIf you use calendar versioning (CalVer) instead of semver, update the versioning section accordinglyAdd a 'Contributing' note linking to your CONTRIBUTING.md if external contributors write entries

Unreleased Section

The [Unreleased] section sits at the top and accumulates all changes that are merged but not yet in a release. When you cut a release, rename this section to the version number and create a new empty [Unreleased] section. This is the core workflow of Keep a Changelog.

Template
## [Unreleased]

### Added
- [New feature or capability — describe what users can now do, not just what code changed]
- [New API endpoint: `POST /api/v2/reports` for programmatic report generation]

### Changed
- [Existing behavior that changed — explain the before and after]
- [Renamed `user_id` to `userId` in all API responses for consistency]

### Deprecated
- [Feature that still works but will be removed — include the planned removal version]
- [`GET /api/v1/stats` is deprecated and will be removed in v3.0.0. Use `GET /api/v2/analytics` instead.]

### Removed
- [Feature that no longer exists — previously deprecated items land here when removed]

### Fixed
- [Bug that was resolved — describe the symptom, not the internal cause]
- [Fixed: dashboard failing to load when user had more than 50 repositories connected]

### Security
- [Any security-relevant fix — always include, even if users don't need to take action]
- [Patched: dependency `package-name` updated to v2.1.1 to address CVE-2026-XXXXX]
Write from the user's perspective — 'Fixed: dashboard failing to load' not 'Fixed: null pointer in DashboardController'Only include sections that have entries — omit empty sections like 'Removed' if nothing was removedFor APIs, always include the exact endpoint or method name so developers can search for itLink PR numbers in parentheses for internal readers: Fixed: dashboard crash (#1234)

Released Version Entry

When you ship a release, cut the Unreleased section into a versioned entry. The date is the release date in ISO 8601 format (YYYY-MM-DD). Link the version to the diff or GitHub release page for full history.

Template
## [1.4.0] — 2026-03-15

### Added
- GitHub Actions integration: connect your workflows and see CI status in daily reports
- New `cycle_time` metric in weekly reports showing average PR open-to-merge time per developer
- Slack command `/gitmore report` to trigger on-demand reports from any channel

### Changed
- Weekly reports now group commits by feature branch instead of by date, making it easier to see what shipped per initiative
- API rate limit increased from 100 to 500 requests per hour for Pro plan users

### Fixed
- Fixed: timezone handling causing reports to show previous day's commits for users in UTC+12
- Fixed: GitLab webhook signature validation failing for repositories with special characters in the name

### Security
- Updated `jsonwebtoken` to v9.0.2 to address token validation vulnerability

[1.4.0]: https://github.com/org/repo/compare/v1.3.0...v1.4.0
Always date releases on the day they actually ship to production, not when development finishedLink each version tag at the bottom to the GitHub/GitLab comparison URL — this makes the diff one click awayFor patch releases, the Fixed section is often the only section — that's fine and expectedNever edit a released version entry — if you made a mistake, add a new patch release that corrects it

Breaking Change Notice

Breaking changes need extra prominence. Users and integrators must see them immediately. Use a bold notice at the start of the version section for any MAJOR version bump or significant breaking API change.

Template
## [2.0.0] — 2026-03-15

> **⚠️ Breaking Changes** — This release contains breaking changes to the API. Read the [migration guide](https://docs.example.com/migration/v2) before upgrading.

### Breaking Changes
- **Removed:** `GET /api/v1/users` endpoint (use `GET /api/v2/members` instead)
- **Renamed:** `report_type` field renamed to `reportKind` in all API responses
- **Changed:** Authentication now requires Bearer tokens. API key authentication is removed.
- **Removed:** `legacyMode` configuration option

### Added
- New v2 API with improved pagination and filtering across all endpoints
- OAuth 2.0 authentication flow in addition to existing token-based auth
- GraphQL API (beta) at `/api/graphql` for flexible data querying

### Migration Guide
See the full [v2 migration guide](https://docs.example.com/migration/v2) for step-by-step upgrade instructions.

[2.0.0]: https://github.com/org/repo/compare/v1.9.0...v2.0.0
Put the migration guide URL in the breaking changes section, not just in release notes — developers search changelogs firstList every breaking change explicitly — 'various API changes' is not acceptable for a major versionGive at least 2 weeks notice in the [Unreleased] section before shipping a breaking changeConsider versioning your API independently from your application (e.g. /api/v2/) so clients can migrate on their timeline

Version Links Footer

At the bottom of your CHANGELOG.md, maintain a list of links that point each version tag to its diff on GitHub or GitLab. This is what makes version numbers clickable in the rendered markdown.

Template
<!-- Version comparison links — keep sorted newest first -->
[Unreleased]: https://github.com/[org]/[repo]/compare/v1.4.0...HEAD
[1.4.0]: https://github.com/[org]/[repo]/compare/v1.3.0...v1.4.0
[1.3.1]: https://github.com/[org]/[repo]/compare/v1.3.0...v1.3.1
[1.3.0]: https://github.com/[org]/[repo]/compare/v1.2.0...v1.3.0
[1.2.0]: https://github.com/[org]/[repo]/compare/v1.1.0...v1.2.0
[1.1.0]: https://github.com/[org]/[repo]/compare/v1.0.0...v1.1.0
[1.0.0]: https://github.com/[org]/[repo]/releases/tag/v1.0.0
Update the [Unreleased] link every time you cut a release so it always points to the latest tagFor GitLab, replace github.com with gitlab.com and adjust the URL patternSome teams use a git tag script that auto-updates this section — worth automating once you have 10+ versionsThe first release (1.0.0) links to the tag itself since there's no previous version to compare against
Pro Tips

Expert advice

1

Write changelog entries from the user's perspective, not the engineer's. 'Fixed: dashboard failing to load for users with 50+ repos' is useful. 'Fixed: NPE in DashboardService.getRepos()' is not. Non-engineers read your changelog too — product managers, support teams, technical writers, and customers.

2

Use conventional commits (feat:, fix:, chore:, docs:, breaking change:) in your commit messages. Tools like standard-version, release-it, and Gitmore can automatically generate a changelog draft from your commit history, turning a 30-minute manual task into a 2-minute review.

3

Never say 'various bug fixes' or 'performance improvements' without specifics. These phrases exist in poor changelogs because the author didn't track what changed. If you don't know what fixed, neither does anyone reading it — or the developer who has to debug a regression.

4

Date your releases consistently in ISO 8601 format (YYYY-MM-DD). This format sorts correctly alphabetically, is unambiguous across locales (unlike 03/15/26), and is the format used by Keep a Changelog and most automated tools.

5

Keep your CHANGELOG.md in the repository root, not in /docs or a wiki. Developers search repos for 'changelog', and the root is where they look first. Making it hard to find means it won't be read — and if it won't be read, it won't be maintained.

6

Gitmore can automatically surface all merged PRs from the past week grouped by type (features, fixes, security), giving you a ready-made draft of your changelog's unreleased section. Connect your GitHub, GitLab, or Bitbucket repo and turn weekly changelog maintenance from a chore into a 5-minute review.

FAQ

Common questions

What is the difference between a changelog and release notes?

A changelog is the full running history of all changes across all versions, maintained in a single CHANGELOG.md file in your repository. Release notes are the subset of information published for a specific release — often written in a more narrative style for a public audience. Most teams maintain a changelog internally and derive release notes from it for each version. GitHub Releases is a common place to publish release notes while CHANGELOG.md serves as the canonical source of truth.

Should I write a changelog entry for every commit or every PR?

Write entries for every change that a user, integrator, or developer would care about — not every commit. Internal refactors, test additions, and CI configuration changes don't need changelog entries. New features, behavior changes, bug fixes that users would notice, deprecated APIs, and security patches always need entries. A good rule: if a user would open a support ticket about it or a developer would update their integration for it, it needs an entry.

How do I handle breaking changes in a changelog?

Breaking changes deserve maximum visibility. Use a MAJOR version bump (semver), add a prominent warning block at the top of the version section, list every breaking change explicitly under a 'Breaking Changes' heading, and link to a migration guide. Give advance notice in the [Unreleased] section at least one release cycle before shipping. The goal is zero surprises for anyone upgrading.

Can changelogs be generated automatically from git commits?

Yes, if your team uses conventional commits (prefixing messages with feat:, fix:, docs:, etc.). Tools like standard-version, release-it, and semantic-release parse these prefixes and generate changelog drafts automatically. Gitmore takes a different approach: it analyzes your merged PRs and commit patterns to generate a weekly summary of what shipped, which you can use as the basis for your changelog's unreleased section — even without strict commit conventions.

Should I keep one CHANGELOG.md for a monorepo?

No — monorepos typically need one changelog per independently versioned package. If all packages share a single version and deploy together, one file works. But if different packages have different release cadences or version numbers (common in monorepos using Lerna, Turborepo, or Nx), maintain separate CHANGELOG.md files in each package directory. Tools like Changesets are designed specifically for monorepo changelog management.

Automate Your Git Reporting

Stop filling in templates manually. Connect your git provider and let Gitmore generate reports automatically — daily, weekly, or on demand.

Get Started Free

No credit card • No sales call • Reports in 2 minutes