LogoPear Docs
How ToRelease & distribute your app

Publish a changelog for your app

Ship a CHANGELOG.md with your Pear app so users read release notes over peer-to-peer with the pear changelog command.

Any Pear application can ship a CHANGELOG.md. Stage it with the rest of your project and your users—or any third party—read your release notes straight from the app drive with pear changelog pear://<link>, semver-filtered and pretty-printed. It is the same command that prints the Pear platform's own changelog when you run pear changelog with no link.

The changelog lives in the app's Hyperdrive, so it is versioned, replicated, and readable peer-to-peer with no server and no separate publishing step—it travels with every stage and provision.

This is your application's own changelog. It is distinct from the docs-team Release Overview, which is a curated view of changes across Pear and its modules. To publish release notes for your app, follow this guide.

How it works

pear changelog reads a single file at the root of your app drive: /CHANGELOG.md. Under the hood the pear-changelog module parses it into one entry per release, then the command filters by version and prints each entry's notes. The filename and drive-root location are the entire contract—there is no manifest field to set and nothing to register.

Write CHANGELOG.md

Create a CHANGELOG.md at your project root (next to package.json). The format is lightweight:

  • A header block at the top (typically a # Title)—everything before the first ## heading is ignored by the parser. Don't start the file with a ## heading: the parser only recognizes headings that follow a line, so the first release would be dropped.
  • One release per level-2 heading (## <version>), newest first.
  • The first space-separated token of each heading must be a SemVer version (a leading v is allowed and stripped). Everything under a heading until the next ## is free-form Markdown.
CHANGELOG.md
# Acme Chat Changelog

## v1.2.0

### Features
- Group threads with @mentions.

### Fixes
- Reconnect automatically after the sidecar restarts.

## v1.1.0

### Features
- Full-text message search.

## v1.0.0

Initial release.

Keep the version as the first word of the heading, followed by a space. Bracketed Keep a Changelog headings such as ## [1.2.0] - 2026-01-01 aren't valid versions—those releases drop out of the default view and of any --of range (only --full still shows them). Use ## v1.2.0 or ## 1.2.0 instead. You can still add a date after the version, for example, ## v1.2.0 — 2026-01-01.

Check the format locally

Before staging, confirm the file parses the way pear changelog will read it—with the same pear-changelog module the CLI uses. Install it as a dev dependency:

npm install --save-dev pear-changelog

Create check-changelog.js next to the changelog:

check-changelog.js
const { readFileSync } = require('node:fs')
const { parse } = require('pear-changelog')

for (const [version] of parse(readFileSync('CHANGELOG.md'))) {
  console.log('release:', version)
}

Run it with Node:

node check-changelog.js

It prints one line per release the parser found, newest first:

release: v1.2.0
release: v1.1.0
release: v1.0.0

If a release is missing from the output, its heading didn't parse—pear changelog won't show it either.

Stage and seed it with your app

A root CHANGELOG.md is staged like any other project file—no extra flags. Just make sure it is not excluded by a pear.stage.ignore entry or dropped by a pear.stage.only filter that omits it.

Deploying a desktop app? The deployment directory that pear build assembles contains only package.json and by-arch/—your project's CHANGELOG.md is not copied in. Add it before staging: cp CHANGELOG.md ../<name>-<version>/.

pear stage --dry-run pear://<link>   # confirm CHANGELOG.md appears in the diff
pear stage pear://<link>

Then pear seed the link so peers can fetch it. Once staged, the file is retrievable at pear://<link>/CHANGELOG.md. Bump CHANGELOG.md in the same commit as your version bump so each release carries its own notes—see Ship your app for the full stage → provision flow.

Read it back

Anyone with the link reads your changelog with:

pear changelog pear://<link>

By default this prints up to the 10 newest releases within the current major version, each with its full notes, separated by a divider. Tune it with the flags:

FlagEffect
--of <semver>Filter to a version range, for example, --of 1.x.x or --of '>=1.1.0 <2.0.0'. Defaults to the latest major.
--max, -m <n>Cap the number of entries shown (default 10).
--fullShow every release (overrides --max); without --of, it also widens the range to all majors.
--jsonEmit newline-delimited JSON—one tagged object per release plus a final status object. Filter on "tag": "changelog" when scripting.
pear changelog pear://<link> --of 1.x.x     # only the 1.x releases
pear changelog pear://<link> --full         # the entire history
pear changelog pear://<link> --json         # machine-readable

Use it for release announcements

Because the changelog is queryable by version range, it doubles as your source of truth for release notes. When you cut a release, pull the exact entries for the range you shipped and paste them into your announcement:

pear changelog pear://<link> --of '>=1.1.0'   # everything since 1.1.0

Relationship to pear dump

pear changelog is the structured view of the same file that pear dump returns raw:

pear dump pear://<link>/CHANGELOG.md -   # raw Markdown, unparsed, to stdout

Use pear dump when you want the exact file bytes; use pear changelog when you want it parsed, semver-filtered, and formatted.

See also

On this page