A CLI for writing better commits, following the conventional commits specification.
## ✨ Features
- Generate conventional commits through a series of prompts
- Highly configurable with sane defaults
- Infers ticket, commit scope, and commit-type from branch for consistent & fast commits
- Consistent branch / worktree creation with flexible workflow hooks via `better-branch`
- Interactive git status/add on commit
- Preview commit messages in color
- Support for git emojis per commit-type
- Configure globally or per repository
- Config validation and error messaging
- Scriptable and works with agents via CLI flags
- [Lightweight](https://bundlejs.com/?q=better-commits&treeshake=%5B*%5D) (34kb)
As a side-effect of formatting messages
- Auto populate PR title / body
- Automate semantic releases
- Automate changelogs
- Automatically link & close related tickets / issues
## Installation
> Requires Node.js 20 or newer.
```sh
npm install -g better-commits
```
## Usage
To run the CLI in your terminal:
```sh
better-commits # Create a new commit
better-branch # Create a new branch / worktree
```
`better-commits` will prompt a series of questions. These prompts will build a commit message, which you can preview, before confirming the commit. - To better understand these prompts and their intention, read [Conventional Commits Summary](https://www.conventionalcommits.org/en/v1.0.0-beta.4/#summary)
Some of the values in these prompts will be inferred by your branch name and auto populated. You can adjust this in your `.better-commits.jsonc` (or `.better-commits.json`) configuration file.
For documentation on passing commit values to `better-commits` via the CLI, see [CLI Flags](#cli-flags).
> [!TIP]
> The `--no-interactive` flag, allows automated workflows or AI agents like OpenCode and Claude Code, to use better-commits to generate consistent commit messages using less tokens.
>
> Run `better-commits --help` / `better-branch --help` for more information.
## ⚙️ Configuration
### Global
Your first time running `better-commits`, a default config will be generated in your `$HOME` directory, named `.better-commits.jsonc` (formerly `.better-commits.json`)
- This config will be used if a repository-specific config cannot be found.
### Repository
To create a **repository-specific config**, navigate to the root of your project.
- Run `better-commits-init`
- This will create a default config named `.better-commits.jsonc`
- Properties such as `confirm_with_editor` and `overrides` will prefer the global config
### Properties
> [!NOTE]
> All properties are optional and can be removed from the config. They will be replaced by the default at run-time.
>
> - See `.better-commits.json` in this repository as an example
```
…
```
### Inference
`better-commits` will attempt to infer the ticket/issue, commit-type, and commit scope from your branch name. It will auto populate the corresponding field if found.
**Ticket / Issue-Number**
- If a `STRING-NUMBER` or `NUMBER` are at the start of the branch name or after a `/`
**Commit Type**
- If a type is at the start of the branch or is followed by a `/`
**Commit Scope**
- If a configured scope appears as its own branch word, separated by `/`, `-`, or `_`
- If scope appears after a ticket, the expected shape is `TICKET-SCOPE-description`
- Empty scope values and the `custom` scope option are ignored during inference
## Better Branch
Better branch is a secondary feature that works with better commits
- Supports consistent branch naming conventions
- Uses same type-list/prompt from your config
- Enables better-commits to infer type, scope, and ticket
- Caches your username for speedy branching
- Convenient worktree creation and hooks
To run the CLI in your terminal:
```sh
better-branch
```
### Worktree Support
`better-branch` will prompt for **Branch** or **Worktree**. The Worktree flow creates a folder/worktree from your **branch description** and a git branch inside with your **full branch name**.
> [!NOTE]
> Creating a worktree named `everduin94/feat/TAC-123-add-worktrees` with the native git command would create a nested folder for each `/`. `better-branch` removes the hassle by creating 1 folder while still using the full name for the branch.
> [!TIP]
> By default, `better-branch` will create **worktrees** as a sibling folder. To change this, see `worktrees.base_path`.
> [!TIP]
> Use worktrees in a repository often?
>
> You can target your **main** folder for **worktree creation** from any folder (root or sibling)
>
> alias create_worktree='better-branch --checkout worktree --git-dir="MAIN_FOLDER/.git" --work-tree="MAIN_FOLDER"'
### Pre/Post Branch Checkout Hooks
Configure commands to run before or after creating a branch or worktree:
```jsonc
{
"branch_pre_commands": ["git pull -r origin main"],
"branch_post_commands": ["npm install"],
"worktree_pre_commands": ["echo Creating {{TYPE}} for {{TICKET}}"],
"worktree_post_commands": ["npm run setup -- --ticket={{TICKET}}"],
}
```
## Tips & Tricks
### Building / Versioning
`better-commits` works with [Semantic Release](https://github.com/semantic-release/semantic-release)
- See _package.json_ and _.github/workflows/publish.yml_ for example
### Github
If you use `better-commits` to create your _first_ commit on a new branch
- When you open a PR for that branch, it will properly **auto-populate the title and body**.
- When you squash/merge, all later commits like "addressing comments" or "fixing mistake". Will be prefixed with an asterisk for easy deletion. This way, you **maintain your pretty commit even when squashing**.
If you're using Github issues to track your work, and select the `closes` footer option when writing your commit. Github will **automatically link and close** that issue when your **pr is merged**
### Changelogs
`better-commits` can append a commit trailer per commit type. This allows you to [automate change logs](https://docs.gitlab.com/ee/user/project/changelogs.html) with tools like Gitlab.
### Git
`better-commits` uses native `git` commands under the hood. So any hooks, tools, or staging should work as if it was a normal commit.
Setting `confirm_with_editor=true` will allow you to edit/confirm a commit with your editor.
- For example, to edit with Neovim: `git config --global core.editor "nvim"`
- For VS Code, `git config --global core.editor "code -n --wait"`
You can pass arguments to `git` through `better-commits` like so:
```sh
better-commits --git-dir="$HOME/.config" --work-tree="$HOME"
```
A practical example of this would be managing dotfiles, as described in this [Atlassian Article](https://www.atlassian.com/git/tutorials/dotfiles)
### CLI Flags
Use CLI flags to pass commit values directly instead of answering prompts.
- Use `--no-interactive` to skip prompts, confirmation, and editor flows. This is the recommended mode for OpenCode, Claude Code, and other coding agents.
- Use `--dry-run` to validate the generated `git commit` command without creating a commit.
- Supported commit field flags: `--type`, `--scope`, `--title`, `--body`, `--ticket`, `--closes`, `--deprecates`, `--breaking-title`, `--breaking-body`, `--deprecates-title`, `--deprecates-body`, `--custom-footer`, `--trailer`.
- Supported branch field flags: `--user`, `--type`, `--scope`, `--description`, `--ticket`, `--branch-version`, `--checkout`.
- Values like ticket, scope, and type will still attempt to be inferred where possible when using `--no-interactive`
**Examples**
```sh
better-commits --no-interactive --dry-run --type feat --scope cli --title "add parser"
better-branch --no-interactive --type feat --scope cli --ticket TAC-123 --description "add parser" --checkout worktree
```
---
### Troubleshooting Windows
#### Git Bash
`TTY initialization failed: uv_tty_init returned EBADF (bad file descriptor)`. This may happen because you're running something like git-bash on Windows. Try another terminal/command-prompt or `winpty` to see if its still an issue.
#### Multi-line
If you are having issues with multilines for commits on windows, you can override the shell via your `.better-commits.jsonc` config.
Example
```json
"overrides": {
"shell": "c:\\Program Files\\Git\\bin\\bash.exe"
}
```
Sponsors
[Markdown Notetaking - Built for Learning](https://flotes.app)