Commands
chamoji changelog
Write a changelog from your git history. Each release tag becomes a section, and the commits since the last one become Unreleased. It prints Markdown to stdout, or JSON or HTML. It never commits or tags anything.
MONOREPO-AWARE --format json FOR CI AND AGENTS--output replaces the whole file. To add one release’s section to an
existing CHANGELOG.md and leave older entries alone, use chamoji release.
What it does, in order
- Finds the releases. The release tags in the history of
HEAD, or of the ref you give with--to, newest first. - Collects the commits. Each release gets the commits since the tag before it. The commits since the last tag form the Unreleased section.
- Sorts them. Into sections such as Added, Fixed and Documentation, from the gitmoji, the Conventional type or the wording. A shipped workstream becomes one Highlight, and dependency updates become one line.
- Prints it. Markdown to stdout, unless
--formator--outputsay otherwise.
How commits are read has the rules for each step.
Arguments
chamoji changelog takes no arguments.
Flags
- Name
--format <name>- Type
- string · default markdown
- Description
markdown,md(the same),jsonorhtml. Anything else exits 1. Works with every other flag. With--for-tag,jsonandhtmlare built from the history, and Markdown is the notes as the release committed them.
- Name
--output <file>, -o- Type
- string
- Description
Write to this file instead of stdout, and say
Wrote <file>on stderr. The path is from the current folder, and the file is replaced. Works with every other flag.
- Name
--from <tag>- Type
- string
- Description
Leave out this release and everything older. The tag must be a release in the history, or it exits 1. Combines with
--toand--release. Not with--since,--unitor--for-tag.
- Name
--to <ref>- Type
- string · default HEAD
- Description
Treat this ref as the head of history. Commits and tags after it are left out. Combines with
--from,--releaseand--since. With--unitor--for-tag, any ref other thanHEADexits 1.
- Name
--release <version>- Type
- semver
- Description
Name and date the Unreleased section with this version, as when you cut a release. Its compare link points at the tag it will get,
v<version>when your tags use av. A version that isn’t semver exits 1. Not with--since,--unitor--for-tag.
- Name
--since <ref>- Type
- string
- Description
Only the commits after this ref, as one Unreleased section, with no older releases. For previewing a branch:
--since origin/main. Combines with--to. Not with--from,--release,--unitor--for-tag.
- Name
--config <file>- Type
- string · default chamoji.config.json
- Description
Read this config file instead, from a path relative to the current folder. Without it, chamoji reads
chamoji.config.jsonin the current folder, not at the repo root, so run chamoji from the root. A file that doesn’t exist exits 1.
- Name
--ai- Type
- boolean
- Description
Sort the commits no rule can place with Jev, TypeSafe’s classification model. Needs
TYPESAFE_API_KEY, or it exits 1. Works with every other flag. Sorting with AI says what is sent.
- Name
--unit <name>- Type
- string · monorepos
- Since
- SINCE 0.13.0
- Description
This unit’s releases, read from its own tags. Only in a repo with release units, where
changelogneeds this or--for-tag. It takes one unit. Not with--for-tag,--from,--to,--releaseor--since.
- Name
--for-tag <tag>- Type
- string · monorepos
- Since
- SINCE 0.13.0
- Description
Only the release with this tag, from the unit whose tag format fits it. In Markdown, the notes are the ones the release committed. Units in a fixed group that share the tag get a section each. Only in a repo with release units. Not with
--unit,--from,--to,--releaseor--since.
- Name
--no-update-check- Type
- boolean
- Description
Don’t check npm for a newer chamoji. See the update notice.
Common combinations
chamoji changelog --output CHANGELOG.md
Write the whole history to a file.
chamoji changelog --since origin/main
Preview what this branch adds.
chamoji changelog --release 1.4.0
Name and date the next section before you tag it.
chamoji changelog --format json
Every release and commit, for a script or an agent.
chamoji changelog --format html --output changelog.html
A page you can publish as it is.
chamoji changelog --for-tag web/v1.4.0
One unit’s release notes, as the release wrote them.
To name the next section with the version chamoji picks:
version=$(chamoji next-version) && chamoji changelog --release "$version" -o CHANGELOG.md
Output
These are from real runs in a small repo called widgets, with one release, v0.1.0, and three commits since:
chamoji changelog
# Changelog
## Unreleased
### Added
- ✨ Add a range mode to the date picker (3565b84)
### Fixed
- 🐛 Close the dialog on Escape (a13acb6)
### Maintenance
- ✅ Test the range mode (d6e8b65)
## v0.1.0 - 2026-11-05
### Added
- ✨ Add the date picker (937b3c6)
- 🎉 Begin the widgets project (aabb7e9)
### Fixed
- 🐛 Fix focus in the dialog (7776906)
### Documentation
- 📝 Explain the picker's props in the readme (0f7511f)
--release names the Unreleased section and dates it today:
chamoji changelog --release 0.2.0
# Changelog
## 0.2.0 - 2026-11-05
### Added
- ✨ Add a range mode to the date picker (3565b84)
…
--format json gives every release, with each commit’s parsed parts:
chamoji changelog --format json
{
"releases": [
{
"version": "Unreleased",
"tag": null,
"previousTag": "v0.1.0",
"date": null,
"bump": "minor",
"nextVersion": "0.2.0",
"groups": [
{
"group": "added",
"label": "Added",
"commits": [
{
"hash": "3565b847f8828bc2c23612d842e359e58b137630",
"shortHash": "3565b84",
"authorName": "Robin Lane",
"authorEmail": "robin@example.com",
"date": "2026-11-05T01:27:34-07:00",
"subject": "✨ Add a range mode to the date picker",
"body": "",
"gitmoji": "sparkles",
"gitmojiSource": "gitmoji",
"type": null,
"scope": null,
"description": "Add a range mode to the date picker",
"breaking": false,
"trailers": []
}
]
},
…
In shop, a repo whose two apps release on their own, a bare changelog asks which unit:
chamoji changelog
chamoji: this repo releases units (mobile, web); pass --unit <name> or --for-tag <tag>
--unit gives that unit’s releases. A fix in the shared packages/ui is listed with each app it rides along with:
chamoji changelog --unit web
# Changelog
## 1.2.1 - 2026-11-05
### Changed
- 💄 Round the button corners (11fba80) (via `packages/ui`)
### Fixed
- 🐛 Keep the coupon after a page reload (7175e94)
## 1.2.0 - 2026-11-05
### Added
- ✨ Add the checkout page (ab41693)
- 🎉 Begin the shop (51bca17)
### Fixed
- 🐛 Fix the button's focus ring (ae44eff) (via `packages/ui`)
--for-tag gives one release’s notes, as for its GitHub release:
chamoji changelog --for-tag web/v1.2.1
## 1.2.1 - 2026-11-05
### Changed
- 💄 Round the button corners (11fba80) (via `packages/ui`)
### Fixed
- 🐛 Keep the coupon after a page reload (7175e94)
Flags that don’t combine say so:
Errors
$ chamoji changelog --since v0.1.0 --from v0.1.0
chamoji: --since can't be combined with --from or --release
Exit codes
- Name
0- Description
- It printed or wrote the changelog.
- Name
2- Description
The config’s
releasesection is from a newer chamoji.
- Name
1- Description
Anything else, such as an unknown
--format, a--fromtag that isn’t a release, flags that don’t combine, or--unitin a repo without release units.
Exit codes has every command’s codes.
Related
How commits are read
How tags become releases and commits become sections.
release
Add the next section to CHANGELOG.md, then commit and tag it.
GitHub Action
Release notes on every tag and a preview on every pull request.
Config
Rename sections, or set the repository URL for links.