Reference

Config

config.mdEdit on GitHub

chamoji reads chamoji.config.json in the folder you run it from, when there is one, so run chamoji from the repo root. Every key is optional: with no file, you get the default sections, links from origin, and one version for the whole repo.

CONFIG

You don’t have to write the release section by hand. chamoji setup writes it from what it finds in the repo.

The file

chamoji.config.json

{
	"repositoryUrl": "https://github.com/acme/widgets",
	"groups": [
		{"group": "added", "label": "Added", "emojis": ["sparkles", "tada"]},
		{"group": "fixed", "label": "Fixed", "emojis": ["bug", "ambulance"]},
		{
			"group": "useless",
			"label": "Useless",
			"emojis": ["bookmark"],
			"hidden": true
		},
		{"group": "misc", "label": "Miscellaneous", "emojis": []}
	]
}

--config <file> reads another file instead. A file that doesn’t parse, or a key with the wrong type, stops the command with a message that names the key.

Top-level keys

  • Name
    repositoryUrl
    Type
    string
    Description

    The repo’s URL, for commit, issue (#12) and compare links. Default: the origin remote.

  • Name
    groups
    Type
    list of groups
    Description

    The changelog’s sections, in order. It replaces the default sections; it doesn’t add to them. Default: the sections below. A plain JSON array of groups, the older format of this file, is also accepted.

  • Name
    release
    Type
    object
    Since
    SINCE 0.13.0
    Description

    How releases are versioned and tagged. Default: one package, one v* tag and one CHANGELOG.md. See The release section.

A group

  • Name
    group
    Type
    string · required
    Description

    The section’s key, such as added. Commits that match no group go to misc when that group exists.

  • Name
    label
    Type
    string · required
    Description

    The heading in the changelog, such as Added.

  • Name
    emojis
    Type
    list of strings · required
    Description

    Gitmoji codes, such as sparkles for ✨. Colons are dropped, so :sparkles: works too. Conventional types and plain messages land here through the gitmoji they map to.

  • Name
    hidden
    Type
    boolean
    Description

    Match these commits, then leave them out of the output. Default: false.

  • Name
    collapse
    Type
    boolean
    Description

    Render the group as one summary line, as the default Dependencies group does. Default: false.

The default sections

grouplabelNotes
addedAdded✨ 🎉 and other additions
changedChanged♻️ ⚡️ 🎨 ⏪ and other changes
breaking_changesBreaking changes💥, and every commit marked breaking
deprecatedDeprecated🗑️
removedRemoved🔥 🔇 ⚰️
fixedFixed🐛 🚑️ 🩹
securitySecurity🔒️ 🔐 🛂
documentationDocumentation📝 ✏️
maintenanceMaintenance👷 💚 ✅ 🧪
dependenciesDependencies⬆️ ⬇️ 📌 ➕ ➖, collapsed into one line
uselessUseless🔖 🔀, hidden
miscMiscellaneous💡 🚀 🚧 and anything no other group claims

Every official gitmoji is in exactly one of them.

MONOREPOSrelease

The release section

Without a release section, the repo is one package: one version, one v* tag and one CHANGELOG.md. That is also right for a monorepo whose packages ship together. With one, every unit (an app or a package) gets its own version, tag, changelog and GitHub release.

An app monorepo

{
	"release": {
		"schema": 1,
		"shape": "apps",
		"units": {
			"web": {"path": "apps/web", "tag": "web/v{version}"},
			"mobile": {
				"path": "apps/mobile",
				"tag": "mobile/v{version}",
				"versionFiles": ["apps/mobile/app.config.ts"]
			}
		},
		"exclude": ["apps/e2e", "apps/dev-tool", "tooling/*"]
	}
}

A library monorepo

{
	"release": {
		"schema": 1,
		"shape": "libraries",
		"units": {
			"core": {"path": "packages/core"},
			"cli": {"path": "packages/cli"},
			"ui": {"path": "packages/ui"}
		},
		"fixed": [["core", "cli"]]
	}
}

Pin the CLI to 0.13.0 or newer before you add a release section. 0.12.1 refuses it, and 0.12.0 ignores it and cuts one release for the whole repo.

  • Name
    schema
    Type
    1 · required
    Since
    SINCE 0.13.0
    Description

    The section’s format. A higher number is from a newer chamoji, which stops with “this repo’s release settings need chamoji 0.13.0 or newer” and exit code 2.

  • Name
    shape
    Type
    'single' | 'apps' | 'libraries' · required
    Since
    SINCE 0.13.0
    Description

    apps versions each app, libraries each package. single is the default behaviour, one release for the whole repo, and takes no other key.

  • Name
    units
    Type
    object
    Since
    SINCE 0.13.0
    Description

    Each unit by name, with its settings (below). A name can’t be empty or contain / or spaces. Default: none.

  • Name
    exclude
    Type
    list of path globs
    Since
    SINCE 0.13.0
    Description

    Paths that belong to no unit. Commits that change only these are left out. Default: none.

  • Name
    sharedChanges
    Type
    'ride-along' | 'release-dependents'
    Since
    SINCE 0.13.0
    Description

    What a commit to an internal package does. ride-along releases nothing on its own, and goes in each unit’s next release, marked “via packages/…”. release-dependents releases every unit that uses the package, by at least a patch. Default: ride-along for apps, release-dependents for libraries.

  • Name
    rootFiles
    Type
    'none' | 'all' | 'note'
    Since
    SINCE 0.13.0
    Description

    What a commit that changes only files outside every package, such as the lockfile or CI, does. none leaves it out, all counts it for every unit, and note adds a line such as “Tooling and CI: 12 changes” to each unit’s notes. Default: none.

  • Name
    zeroMajor
    Type
    'minor'
    Since
    SINCE 0.13.0
    Description

    Make a breaking change raise the minor version while a unit is at 0.x. Default: unset, so a breaking change raises the major version.

  • Name
    fixed
    Type
    list of lists of unit names
    Since
    SINCE 0.13.0
    Description

    Units that always share one version: the largest bump of any of them. When one releases, they all do. A unit can be in one group only. Default: none.

  • Name
    upstream
    Type
    object
    Since
    SINCE 0.13.0
    Description

    The history of a template you started from, so it stays out of your notes. See upstream. Default: unset.

  • Name
    tags
    Type
    object
    Since
    SINCE 0.13.0
    Description

    ignore and aliases, for tags that aren’t releases or don’t parse. See tags. Default: none of either.

  • Name
    rootChangelog
    Type
    boolean
    Since
    SINCE 0.13.0
    Description

    Add a root CHANGELOG.md that lists every release, with links to the units’ changelogs. Default: false.

  • Name
    githubReleases
    Type
    'per-unit' | 'combined'
    Since
    SINCE 0.13.0
    Description

    One GitHub release per unit, or one per release commit. Default: per-unit.

Every key but schema and shape needs apps or libraries. With single, any other key stops the command.

A unit

Each entry in release.units, such as "web": {"path": "apps/web"}.

  • Name
    path
    Type
    string · required
    Description

    The unit’s folder, from the repo root, such as apps/web. Paths match on whole folder names, so apps/web doesn’t match apps/web-admin.

  • Name
    tag
    Type
    template
    Description

    The tag for a release. {unit} is the unit’s name in units, {name} its package name and {version} the version, which the template must contain. Default: {unit}/v{version} for apps and {name}@{version} for libraries. Two units share a template without {unit} or {name} only in one fixed group.

  • Name
    read
    Type
    list of templates
    Description

    Older formats, such as web-v{version}, to read past releases from. Default: none.

  • Name
    versioning
    Type
    'semver' | 'calver'
    Description

    calver gives date versions: the year, the month and a count of the unit’s releases that month, such as 2026.11.0, with no zero padding. Default: semver.

  • Name
    firstVersion
    Type
    string
    Description

    The version of the unit’s first release, when it has no tag yet. Default: the version in its manifest, or a date version for a calver unit.

  • Name
    versionFiles
    Type
    list of paths
    Description

    Other files that carry the version, such as apps/mobile/app.config.ts, an Info.plist or an android/app/build.gradle. The unit’s package.json is always bumped. A path outside the repo, or a symlink, is refused, and a listed file where chamoji can’t find the version stops the release before anything changes. Default: none.

  • Name
    buildNumber
    Type
    'untouched' | 'increment'
    Description

    increment raises CFBundleVersion, versionCode and Expo’s ios.buildNumber and android.versionCode by one. It does nothing when the app uses EAS remote versioning. Default: untouched.

  • Name
    changelog
    Type
    path
    Description

    Where the unit’s changelog goes, from the repo root. Default: CHANGELOG.md in the unit’s folder.

upstream

For a repo that began as a clone of a template you started from, and keeps pulling from it.

release.upstream

"upstream": {
	"remote": "upstream",
	"name": "Acme Starter",
	"since": "<first commit that is yours>",
	"authors": ["dev@acme-starter.example"]
}

The template’s history is every commit that the remote’s fetched branches reach, that a version-like tag in tags.ignore reaches, or that one of authors wrote. Those commits are left out of every unit’s notes and never release anything. Each merge that brings them in becomes one line, such as “Updated the Acme Starter base to 4.0.2”.

  • Name
    name
    Type
    string · required
    Description

    The template’s name, for the sync lines in your notes.

  • Name
    remote
    Type
    string
    Description

    The template’s remote, which must be fetched. In CI, where the checkout has only origin, add and fetch it before chamoji runs. Default: unset.

  • Name
    since
    Type
    commit or ref
    Description

    Your first commit that isn’t the template’s. Default: unset.

  • Name
    authors
    Type
    list of emails
    Since
    SINCE 0.14.0
    Description

    Commits on HEAD by these authors, compared ignoring case, are the template’s. 0.13.0 accepts the key and ignores it. Default: none.

tags

release.tags

"tags": {
	"aliases": {"final-release": {"unit": "web", "version": "1.0.0"}},
	"ignore": ["^\\d+\\.\\d+\\.\\d+$", "^wip/"]
}
  • Name
    ignore
    Type
    list of regular expressions
    Description

    Tags that aren’t releases, such as ones that came with a template. These are regular expressions, not globs: ^wip/ matches tags that start with wip/. Default: none.

  • Name
    aliases
    Type
    object
    Description

    A version for a tag that doesn’t parse but is a real release, as {unit, version}. With one unit, the value can be the version string alone. Default: none.

chamoji never moves, deletes or renames a tag. Tags that match nothing stay in git, untouched.

Settings kept elsewhere

Two things aren’t in chamoji.config.json:

  • The commit composer reads gitmoji-cli’s settings, from .gitmojirc.json or the gitmoji key in package.json: emojiFormat (emoji or code; default emoji), and scopePrompt, messagePrompt, capitalizeTitle and autoAdd (default true, true, true and false).
  • Suggestions from Jev are opt-ins in git config, chamoji.composer and chamoji.sendDiffs, so a repo you clone can’t switch them on for you.

Was this page helpful?