Design system changelogs: shipping changes to people who build with your components
A design system is a strange thing to ship. It has no screens of its own — every change you make lands in someone else’s product, wearing someone else’s deadlines. Your users are colleagues (or, for open systems like Material or Carbon, strangers) who chose your buttons over building their own, and who re-make that choice at every upgrade. And each release ships to two different audiences at once: developers bumping an npm package, and designers swapping a Figma library. One change, two readers, two vocabularies.
That makes the changelog load-bearing in a way most products never experience. It’s not marketing — it’s the upgrade contract between your team and every team that builds on you. This guide covers what’s different about writing it: the dual-artifact problem, what “breaking” really means when the interface is visual, design tokens as an API, and how to write for the team doing the upgrading.
One change, two artifacts
Most software has one deliverable. A design system has at least two — a code package and a design library — plus usually a docs site, and they don’t version together. npm gives the code semver; Figma gives the library a “publish” button and a free-text note. The skew between them is where adopting teams get hurt: a designer works from library v2 mockups while the codebase still has v1 components, and nobody can say which “Button” the spec means.
The changelog is the cheapest place to stitch the artifacts back together. Two rules do most of the work:
- One entry per logical change, speaking to both readers. Don’t run a developers’ changelog and a designers’ changelog that drift apart. One dated entry: what changed, what it means in code, what it means in the design file. Readers skip the half that isn’t theirs — that’s fine, it’s one URL either way.
- State the artifact versions in the entry. “Shipped in
@acme/ui 4.2.0; Figma library update published the same day” costs one line and answers the skew question forever. If the Figma side lags — it usually does — say so: “Figma update follows next week; code is safe to adopt now.”
“Breaking” is bigger when the interface is visual
For a library, breaking means the API changed. A design system’s API is wider than its props, because anything observable gets depended on — and in UI, nearly everything is observable. Treat all of these as changelog-worthy, and the starred ones as breaking no matter what semver says about the props:
- Prop renames, removals, and default changes — the classic kind; ordinary semver rules apply.
- Visual changes* . A new focus ring, a different border radius, a spacing bump — semver says patch, but every visual-regression suite downstream goes red, and every product screenshot in every deck quietly goes stale. A visual change that will fail someone’s snapshot tests deserves the same prominence as a prop removal.
- DOM structure and class-name changes* . Teams style your internals with
CSS overrides you never sanctioned. You don’t have to support that — but a
changelog entry saying “Button’s internal markup changed; overrides targeting
.btn__iconwill break” turns a mystery regression into a five-minute fix. - Token renames and value changes* — covered below; renames are API breaks, value changes are visual changes.
- Accessibility and behavior changes. New keyboard handling, changed focus order, an added live region — invisible in a screenshot, very visible to users and to downstream tests that script the component.
- Peer dependency and minimum-platform bumps — dropping a framework major or browser target is breaking for whoever’s still on it.
The honest summary: in a design system, “no API changes” does not mean “nothing to announce.” If screens will look or behave differently after the bump, the entry must say so — ideally with a before/after screenshot, which answers in two seconds what a paragraph can’t.
Design tokens are an API — version them like one
Tokens (color-action-primary, space-300…) are the design
system’s deepest interface: referenced in thousands of places you’ll never see, by name.
That gives them exactly the semantics of a programming API:
- Renaming or removing a token is a breaking change. Ship an alias for the old name for a full deprecation window, mark it deprecated in the entry with its removal date, and announce it three times like any other removal.
- Changing a token’s value is a visual change everywhere at once. Give
exact before → after values — “
space-300: 12px → 16px” — the same way good patch notes give exact numbers. “Adjusted spacing tokens” forces every team to diff your system for you. - New tokens are the good news. They’re also the entries that teach teams tokens exist — name the use case, not just the token.
Write for the adopting team
Your reader is upgrading on purpose, usually weeks after release, usually several versions at once, on time budgeted from their own roadmap. The entry that respects that answers, in order:
- Will anything change on my screens if I do nothing but bump? The scariest category — visual and behavior changes that arrive without any code edits. Lead with it, even (especially) when the honest answer is “yes, the focus ring on every input changes.”
- What do I have to change by hand? Renamed props, removed components,
replaced tokens — with a migration path per item. If you shipped a codemod, that’s
the first line: “run
npx @acme/ui-codemod v4, it handles items 1–3.” - How long will this take? An honest effort estimate — “most apps: under an hour; heavy Table users: budget an afternoon” — is rare enough to be a trust signal all by itself.
- What’s in it for us? The upgrade’s sales pitch: the new component, the a11y win, the bug that’s finally fixed. Adoption is voluntary — the changelog is where you earn it.
A release entry skeleton
## v4.2.0 — <date> (Figma library updated same day) **If you only bump:** Input and Select focus rings change to the new 2px style (before/after below). Nothing else visual moves. **Migration (≈30 min for most apps):** - `Button`: `kind` prop renamed to `variant` — codemod handles it: `npx @acme/ui-codemod v4-2` - Token `color-brand-alt` deprecated (alias until v5, <date>) — use `color-accent-secondary` **New** - DatePicker: range selection (docs + Figma component ready) **Fixed** - Modal: focus no longer escapes to the page behind (keyboard trap)
Sections you don’t need, delete — a template is a checklist, not a mad-lib.
Distribution: the changelog is your adoption campaign
Design systems have a problem most products don’t: your users can simply… not upgrade, forever. The changelog is your standing argument against that, which means it has to reach people, not just exist:
- A canonical dated page with per-release permalinks — the thing you link from migration PRs, support threads, and design reviews. For internal systems this is the internal changelog pattern; it works unlisted just as well.
- A chat mirror — title + one line + permalink into the #design-system channel via webhook, not a wall of text. Chat announces; the page remembers.
- Notes where the components live — link the changelog from Storybook’s docs panel and from the Figma library description, so both audiences find it from the tool they’re already in.
- Screenshots for anything visual. One before/after pair outperforms any prose. Designers especially will read the pictures first — let them.
Anti-patterns
- The monorepo commit dump. Changesets and friends will happily publish “fix: sync tokens (#2314)” × 40 as your release notes. Generated output is a draft, not a changelog — curate it into the skeleton above. (Monorepo changelogs have their own guide.)
- “Visual refinements” with no pictures and no list. The reader’s only options are diffing your Figma file or getting surprised in production. Both cost them an afternoon; a screenshot costs you a minute.
- Code and Figma versioned separately with no map. If nobody can say which
library version matches
@acme/ui 4.2, every design review starts with archaeology. One line per entry fixes it. - Token renames as patch releases. A rename with no alias breaks every referencing file, stylesheet, and plugin. API rules apply: deprecate, alias, announce, then remove.
- Announce-only-in-Slack. Chat is a notification, not an archive; the team that upgrades six months later finds nothing. Pointer in chat, entry on the page.
- Breaking changes filed under “Improved.” If someone must act, the entry says so structurally — a Breaking label, not a cheerful adjective. Trust, as everywhere in changelogs, is the entire product.
Running it on Wakelog
Wakelog fits the shape of this problem well: one project per design system (public for
open-source systems, unlisted for internal ones), dated entries with
per-release permalinks you can drop into migration PRs and Figma descriptions,
tags to mark breaking releases loudly, and a Discord/Slack
webhook so every publish mirrors itself into your #design-system channel. Releases can
post themselves: a curl from CI at
publish time, drafted from your Changesets output. The embed widget
drops into a Storybook docs page, so “what’s new” lives next to the components
themselves. Honest caveat: Wakelog won’t screenshot your components or diff your Figma
file — the before/after images are still on you (link or embed them in the entry body,
which is full markdown).
Start your design system’s changelog Next: release notes for CLI tools & libraries →
Related guides
- Screenshots, GIFs, and video in release notes: when visuals earn their place
A picture of the change is the highest-bandwidth line in your changelog — and also the heaviest, most distracting, least accessible thing you can add to it. The medium ladder from cropped screenshot to demo video, when motion actually earns a loop, and why every entry still has to work with images turned off. - Monorepo changelogs: one changelog or many?
Per-package or one big file? The rule that decides it, what Changesets and release-please actually do, and how to keep a human-readable stream on top. - Platform engineering changelogs: release notes for your internal developer platform
A platform team ships a real product to the strangest user base in software: engineers who never chose it and can’t leave. Every release lands inside someone else’s repo, breaks builds on commits that touched nothing, and gets enforced by deadline. What a paved-road changelog announces, why entries should be findable by error message, and the template that keeps internal customers on the road.
Last updated 2026-07-28 · All guides