Comparatif

GitHub Releases vs Public Changelog: Two Surfaces, One Source of Truth

GitHub Releases or a public changelog page? The honest answer for most SaaS teams is both — with one source of truth feeding each surface. Here's how.

Photo of ReleaseGlow TeamReleaseGlow Team
April 27, 2026
12 min read

The question gets posed as a binary almost every time it comes up on Hacker News or in an engineering Slack: "Should we use GitHub Releases or a proper changelog page?" The framing is wrong. GitHub Releases and a public changelog are two different surfaces serving two different audiences from — ideally — one source of truth. The teams that get release communication right rarely pick one. They wire both up and let each do what it's good at.

This post is the operational answer to that question: who each surface is for, when each one alone is enough, when you need both, and the workflow to keep them in sync without copying anything by hand.

TL;DR

  • GitHub Releases is for people who read code: contributors, integrators, downstream maintainers. It lives next to git tags. Audience is technical.
  • A public changelog page is for people who use the product: customers, PMs, support, prospects. It lives on your marketing domain. Audience is mixed.
  • Most B2B SaaS with both an open-source component and paying customers needs both, not one.
  • Keep one source of truth. The git tag annotation, an MDX file, or a CMS entry — pick one, generate the rest.
  • Decision tree below: open-source library, dev tool, B2B SaaS, consumer app each have different right answers.

What GitHub Releases is actually for

GitHub Releases is a feature attached to git tags. You push a tag, GitHub surfaces it under /releases, and that page renders Markdown release notes plus the source archive and any binary assets you upload. It's optimized for a very specific reader: someone who already knows your repo exists and is making a versioning decision.

Concretely, that's:

  • Contributors scanning what shipped since the last tag they cared about.
  • Library consumers deciding whether to bump from 2.4.x to 2.5.0 and what the migration cost looks like.
  • Distribution channels — Homebrew, apt, Docker Hub mirrors, dependency bots like Renovate and Dependabot — that read the Releases API to build their own metadata.
  • Integrators wiring up a webhook on release.published to trigger their CI or notify their team.

The format is purpose-built for those readers. It assumes familiarity with semantic versioning, links commits and PRs by number, expects "Breaking changes / Features / Fixes" sections in roughly that order, and treats each release as a self-contained diff between two tags. It doesn't try to sell anything. There's no hero image, no marketing copy, no CTA.

What a public changelog is for

A public changelog page lives on your marketing domain — yourcompany.com/changelog — and is built for an audience that overlaps with, but is much wider than, the GitHub readership. The changelog is a product surface. The changelogs that get studied (see our breakdown of Stripe, Linear, and Vercel) treat it that way.

Concretely, the audience is:

  • Existing customers checking what's new since they last logged in.
  • Product managers at customer accounts trying to justify the renewal internally.
  • Support agents triangulating "is this a bug or new behavior?".
  • Prospects doing pre-sales due diligence on velocity.
  • Search engines — yes, the changelog is an SEO asset; long-tail queries land here.

The format is broader. Hero images. Embedded video. Opinionated copy. Author attribution. Tag filters by audience or product area. RSS for the developer subset, email digests for the PM subset, in-app banners for the active user subset. JSON-LD Article schemas for the search engine. None of that fits in a GitHub Release.

The decision tree

Pick the row that matches your product. The right answer is rarely "only one".

| Product type | GitHub Releases | Public changelog | Why | |---|---|---|---| | Open-source library (no SaaS) | Primary | Optional | Audience is engineers reading code. A page is overhead. | | Dev tool / CLI with hosted component | Primary | Secondary | GitHub for the tool, page for the hosted features. | | B2B SaaS with public API | Secondary | Primary | API consumers want a versioned endpoint changelog; non-API users need the page. | | B2B SaaS, no public OSS | Skip | Primary | GitHub Releases would be empty theatre. | | Consumer app | Skip | Primary | App store release notes + a page. GitHub is irrelevant. |

The mistake that keeps showing up: B2B SaaS teams who shipped a small CLI on GitHub three years ago, treat that repo's Releases as their "official" changelog, and never build a customer-facing page. Their CSMs end up writing email summaries by hand because nobody on the customer side reads github.com/yourorg/cli/releases.

One entry, two surfaces, zero duplication

ReleaseGlow lets you write a release once and push it to your public changelog page, an in-app widget, an email digest, and an RSS feed — while your GitHub Releases stay clean and engineering-owned.

Side-by-side comparison

Real-world patterns

The shipped patterns from teams everyone studies:

  • Stripe — both surfaces, separate cadences. Stripe runs a marketing-flavored blog/changelog and a separate API version log. The OSS libraries (stripe-node, stripe-python, etc.) all maintain GitHub Releases independently. Three surfaces, three audiences, no overlap. The discipline is what makes it work.
  • Vercel — page primary, GitHub secondary. vercel.com/changelog is the canonical surface. The Next.js repo on GitHub maintains its own Releases, but the platform changelog lives on the marketing domain because that's where customers go.
  • Linear — page only, no GitHub Releases. Linear has no public OSS, so there's no GitHub repo to attach Releases to. The weekly Wednesday post on linear.app/changelog is the entire surface. No regrets, no compromise.
  • Tailwind — GitHub primary. Tailwind CSS publishes detailed GitHub Releases that double as the official changelog for the OSS project. The Tailwind UI marketing site has its own announcements page for the paid product. Two products, two surfaces, both right for their context.

The pattern: the right shape follows the shape of your product, not a universal rule.

The workflow: git tag to changelog page

The teams that keep both surfaces in sync use one source of truth and generate the rest. Three workable patterns, ranked by automation level:

1. Git tag is the source. A CI job runs on git tag. It reads the annotated tag message (or the merged PR titles since the last tag), generates GitHub Release notes via the Releases API, then POSTs the same body to your changelog platform's API. Tools like semantic-release and release-please do most of this out of the box. See our automated release notes guide for the full pipeline.

2. PR labels are the source. PRs are labeled breaking, feature, fix, internal. A GitHub Action runs nightly, groups merged PRs by label since the last release, drafts a Release, and a human edits and publishes. The same draft pushes to the changelog page on publish. This is what Vercel-style workflows look like internally.

3. The changelog page is the source. Engineers don't write release notes; PMs do, in the changelog tool. On publish, a webhook creates the matching GitHub Release. This is the right model when your audience is mostly non-technical and engineering velocity exceeds editorial bandwidth.

The annotated tag is underrated

If you're going to pick one source of truth and you have a strong engineering culture, make it the annotated git tag. git tag -a v2.5.0 -F notes.md puts the release notes in the repo's own history. Anyone with the repo has the full release history offline. GitHub can't take it away. Your changelog tool can read it via webhook on push.

Common pitfalls

The recurring failure modes, in rough order of frequency:

  • Two surfaces, two truths. GitHub Release says one thing, the page says another, customers find both, support spends an afternoon reconciling. The fix is a single source plus one-way sync. Never edit on both sides.
  • Stale GitHub Releases. Team builds a fancy page, GitHub Releases page goes silent for six months, dependency bots and integrators stop trusting it. If you keep the repo public, keep the Releases moving — even auto-generated stubs are better than silence.
  • Marketing copy on GitHub Releases. Hero images, hype language, and CTAs in GitHub Releases alienate the audience that came to scan a diff. Keep GitHub clinical.
  • Engineering-only changelog page. The opposite mistake — the page reads like raw commit messages because engineering writes it without editorial review. PMs and customers bounce. Editorial layer is mandatory.
  • No version-to-page mapping. A customer reads about a feature on the page, can't tell which version it shipped in, can't pin their dependency. Always link the page entry to a vX.Y.Z GitHub Release.
  • Forgetting the Keep a Changelog vocabulary. Added / Changed / Deprecated / Removed / Fixed / Security. Both surfaces benefit from the same six verbs. Drift creates ambiguity.

Stop choosing — ship to both

ReleaseGlow auto-syncs your GitHub Releases with a designed public changelog, in-app widget, and email digest. One entry, every surface, always in sync.

Bottom line

The framing of "GitHub Releases vs public changelog" is the wrong frame. The right frame is: who is the audience for each surface, and what's the single source of truth that feeds both? Pick the source — annotated tag, PR labels, or CMS entry — pick the one-way automation, and let each surface optimize for its own readership. Open source teams lean GitHub-primary. B2B SaaS teams lean page-primary. Most serious products end up running both, on schedule, in sync, with engineering owning the diff and product owning the narrative.

That's the boring answer, and it's the one that doesn't churn customers or alienate contributors.