How to announce breaking changes
Documenting a breaking change is half the job. The other half is making sure the people it affects hear about it before it bites: ideally one release before it ships, again on release day, and in the places they already look.
Updated 5 min readBreaking changes, deprecations and versioning
The short answer
- Announce at three moments: when you deprecate, when you ship the major, and afterwards while people migrate.
- Deprecate in a minor release first, with a runtime warning that names the replacement.
- On release day, put breaking changes at the top of the notes and link a migration guide.
- Reach people where they are: release notes, a GitHub release, runtime warnings, a pinned issue or discussion, and your docs.
- Say how long the old major version gets fixes, or that it doesn't.
Breaking-change announcement template
Use it for a GitHub discussion, a blog post or a pinned issue, ideally one release before the major ships. Link it from the release notes.
# my-lib 3.0 is coming: what changes and how to prepare
**TL;DR:** 3.0 (planned for <month/year, or "the next major">) removes
<what>. If you <who is affected>, you'll need to <action>.
Everything else keeps working.
## What's changing
- **<Change 1>.** Why: <one sentence>.
- **<Change 2>.** Why: <one sentence>.
## Am I affected?
You're affected if you <condition>. To check, <command or search>.
Since 2.8.0 you'll also see a deprecation warning when you <trigger>.
## How to migrate
1. Upgrade to 2.8 and fix the deprecation warnings.
2. <Specific code change, with before and after.>
3. Upgrade to 3.0 and run your tests.
Full guide: <link to the migration guide>
## Support for 2.x
2.x gets <security fixes until DATE | no further releases>.
## Questions
Ask in <discussion or issue link>.Angle brackets mark what to replace. Delete any section you can't fill in honestly, such as a support window you haven't decided on.
Free tool · no sign-up
Check that your breaking changes come through
Paste a GitHub release or CHANGELOG.md link and see which breaking changes, migration steps and deprecations a coding agent would actually find, as JSON plus an llms.txt summary.
No AI and nothing stored. Or paste a CHANGELOG.md instead
01Before: deprecate in a minor release
The kindest breaking change is one people saw coming. In a minor release before the major, keep the old behavior working, emit a deprecation warning that names the replacement, and list it under Deprecated in the changelog with the planned removal version, or ‘not yet scheduled’.
Runtime warnings reach people who never read release notes: Node.js has util.deprecate(), and Python has DeprecationWarning and, since 3.13, @warnings.deprecated. Large projects publish their plan in one place; Django keeps a deprecation timeline of what each upcoming version will remove. For wording, see how to write deprecation notices.
02Release day: lead with the break
In the major release, breaking changes go first, each with who is affected and what to change. Link a migration guide when a change needs more than a few lines. Python's ‘What's New’ pages have a dedicated ‘Porting to Python 3.x’ section, and Vite publishes a migration guide for each major.
If a change is mechanical, a codemod can do the work. Next.js, for example, ships upgrade codemods you run with npx @next/codemod. Mention yours in the notes: it turns ‘read this guide’ into ‘run this command’. The entry itself should follow how to document breaking changes.
03Use every channel your users read
| Channel | Reaches | Use it for |
|---|---|---|
| CHANGELOG.md and release notes | People who check before upgrading | The authoritative list, with migration steps |
| GitHub release | People watching the repository's releases | Highlights and a link to the notes |
| Runtime deprecation warnings | Everyone still calling the old API, in their terminal and test output | The warning, a release or more before removal |
| Pinned issue or discussion | People who come to the repository with a problem | Questions and migration help in one place |
| Docs: migration guide and version banner | People reading the docs for the version they use | The step-by-step upgrade |
| Blog, newsletter, social | Your wider community | The why and the timeline |
| Structured feed or MCP server | Coding agents doing the upgrade | Machine-readable breaking changes and migration steps |
The last row is new territory for most projects: see changelogs for AI coding agents.
04After: support the migration
Say how long the previous major gets fixes, and stick to it. Watch issues for upgrade failures in the first weeks and add what you learn to the migration guide; people hit the same snags.
05What not to do
- Don't ship a breaking change in a minor or patch release. Under Semantic Versioning, incompatible API changes need a new major version (from 1.0.0 on).
- Don't change a version you've already released. Publish a fix instead.
- Don't bury the break in a long ‘Changed’ list, or only in a commit footer.
- Don't announce a removal date you haven't committed to. ‘Not yet scheduled’ is an honest answer.
Real projects that do this well
Public release notes worth copying from. Each link opens the project's own page.
- Django deprecation timeline Lists, version by version, what will be removed, so every deprecation has a public deadline.
- Python “Porting to” sections Each “What's New” page has a “Porting to Python 3.12” section: the code changes an upgrade may need, in one place.
- Vite migration guide A dedicated page for each major, linked from the changelog, so the release notes stay short.
- Next.js codemods Upgrade steps that can be automated ship as codemods, run with npx @next/codemod.
Before and after
Too vague
v3 is out! Lots of breaking changes, check the commits.
Specific and actionable
3.0 removes config.apiKey, deprecated with a warning since 2.8. If you set apiKey, create a scoped token and set config.token instead; the codemod updates call sites for you. 2.x gets security fixes until YYYY-MM-DD.
Fictional example: use your own verified names, versions and behavior.
LogPulse
Generate release notes with LogPulse
LogPulse is a hosted changelog that people and coding agents can both read. Here's exactly what it can do for the steps above, and what it can't.
Check your changelog, free
Paste a CHANGELOG.md or a GitHub releases link. A deterministic parser (no AI, nothing stored) shows the versions, breaking changes, migration steps and deprecations an agent can extract.
Draft notes from GitHub
Connect a repository: merged pull requests, commits to your default branch and published GitHub releases collect in an inbox. AI drafts a note in the tone you pick, listing breaking changes and deprecations only when the changes clearly show them. Nothing is published until you approve it. 3 AI drafts on Free; unlimited on Open source and Pro. Pro opens soon: .
Publish once, read everywhere
Approved notes go to a hosted changelog and an in-app widget, to email subscribers on Open source and Pro (Pro opens soon), and to a JSON feed and MCP server coding agents can query. CI and agents can publish with an API key.
What it doesn't do: LogPulse doesn't tag releases, bump versions, publish to npm or PyPI, or write CHANGELOG.md back to your repository; keep your release tooling for those. AI drafts can miss context, so review them like a pull request.
Before you publish
- Deprecated, with a warning, at least one minor release before removal where possible
- The announcement says who is affected and how to check
- The migration guide is linked from the release notes
- The support window for the old major is stated
- There's one pinned place for questions
- Breaking changes are published in structured fields for agents
Common questions
How far in advance should I announce a breaking change?
There's no universal rule: it depends on how hard the migration is and how quickly your users upgrade. A common pattern is to deprecate in at least one minor release before the major, so people see warnings while their code still works. Whatever you choose, publish the timeline.
Is changing a default value a breaking change?
If existing code silently behaves differently after the upgrade, treat it as breaking: announce it, ship it in a major version and, where you can, keep the old behavior available as an option.
Do 0.x releases need breaking-change announcements?
Yes. Semantic Versioning allows anything to change in 0.y.z, but your users still need to know what broke. Put a Breaking changes heading in 0.x release notes too.
How do coding agents learn about my breaking changes?
From whatever they can read: release notes, changelogs and, most reliably, structured data. LogPulse publishes each breaking change with its migration steps in a JSON feed and over MCP, so an agent can ask what changed between two versions. The agent still needs tests to confirm the upgrade worked.
Sources
Read next
How to document breaking changes
Write breaking changes people can migrate from: who is affected, old and new usage, deployment order, rollback limits and a test that proves the upgrade worked.
Read the guide Breaking changes, deprecations and versioningHow to write deprecation notices
Say what is deprecated, what replaces it and when it will be removed, without inventing deadlines. A before/after deprecation notice and a 5-point checklist.
Read the guide Open-source libraries and packagesHow to write release notes for open-source libraries
How to write release notes: a copy-paste template, 3 examples (library, CLI, breaking change), a 7-point checklist and how Django and Node.js do it.
Read the guide Breaking changes, deprecations and versioningChangelogs for AI coding agents
Help coding agents upgrade your library correctly: real versions, explicit breaking changes and deprecations, and a machine-readable JSON feed or MCP server.
Read the guide SaaS, APIs and appsHow to write release notes for mobile apps
Write iOS and Android release notes that say which version and platform changed, when the update reaches users, OS requirements and what happens to local data.
Read the guideMore guides: breaking changes, deprecations and versioning
- How to track breaking changes in your npm dependencies
- Semantic versioning cheat sheet for changelogs
Tools and resources
LogPulse
Changelogs coding agents can upgrade from.
Publish versions, breaking changes, migration steps and deprecations once. People get a widget and hosted changelog; agents get a JSON feed and MCP server. Free for open source.