gitversionjs
v1.4.0
Published
Auto-generates SemVer versions from Git tags and branches, GitFlow-style.
Maintainers
Readme
GitVersionJS
GitVersionJS is a tiny tool that turns your Git tags & branches into a semantic version. Use it as a global CLI or as a library.
Note: AI-assisted tooling is now involved in maintenance of this project. Changes may be drafted, reviewed, or refined with AI support, with final repository decisions still made in this codebase.
Features
- Infers version from Git:
- Uses the latest reachable tag from the current
HEAD(e.g.v1.2.3or1.2.3) - Applies branch rules (e.g.
develop,feature/*,release/*,hotfix/*)
- Uses the latest reachable tag from the current
- Configurable tag prefix & branch naming
- Works locally and in CI
- Zero runtime deps for consumers
- Includes a
.buildnumber (commit count) in the version string.
Quick start (CLI – global)
# install globally
npm install -g gitversionjs
# print a version for the current repo
gitversionjs
# JSON output (machine-friendly)
gitversionjs --output json
# run against another repository directory
gitversionjs --cwd /path/to/repo --output jsonTip: you can also run without installing globally:
npx gitversionjs --output json
CLI usage
Usage: gitversionjs [options]
Generate semantic version from Git tags and branches
Options:
--output <format> Output format: text or json (default: "text")
--cwd <path> Path to repository root
--no-include-commits Exclude commit list from JSON output
-h, --help display help for commandLibrary usage (Node ESM)
import { gitversion } from "gitversionjs";
const info = await gitversion(); // { version, major, minor, patch, branch, tag, branchType, timestamp, commits }
console.log(info.version); // e.g. "1.2.0.5", "1.3.0.1724329999"
/// optional: target a specific repo directory
const infoFromOtherRepo = await gitversion({ cwd: "/path/to/repo" });Configuration
Create a .gitversion.config.js in your repo root (ESM):
/** @type {import('gitversionjs').GitVersionConfig} */
export default {
tagPrefix: "v", // e.g. "v1.2.3" → strip "v"
// Branch types or branch name prefixes that should bump patch.
// Defaults to ["develop", "feature"] when omitted.
bump: ["develop", "feature"],
branchPrefixes: {
main: "main",
develop: "develop",
feature: "feature/",
bugfix: "bugfix/",
release: "release/",
hotfix: "hotfix/",
support: "support/",
},
// Optional: extract a version from custom branch names.
// Numeric capture groups become major, minor, patch.
branchRegex: /^(?:hotfix|release)\/R(\d+)-(\d+)\.(\d+)$/,
// Optional strategy presets: "gitflow" (default), "github-flow",
// "trunk-based", "gitlab-flow", or "release-train".
strategy: "gitflow",
// Optional rule overrides. First matching rule wins.
branchRules: [
{ name: "next", match: { exact: "next" }, increment: "minor" },
{ name: "breaking", match: { prefix: "breaking/" }, increment: "major" },
{ name: "preview", match: { regex: "^preview/" }, increment: "patch" },
],
};How versions are determined (default rules)
- Tags: latest reachable semver tag (prefix optional) is the base (e.g.
v1.2.3or1.2.3) - main: exactly the base tag, with
.buildappended (e.g.,1.2.3.5). - develop/feature/: bump patch, append
.build(commit count)
(e.g.1.2.3→1.2.4.5). - Configurable bumping: set
bumpto the branch types or branch name prefixes that should bump patch, for example["dev", "feature/", "hotfix"]. Branches not matched bybumpkeep the base version and append.build. - Configurable branch rules: set
branchRulesfor exact, prefix, regex, or branch-type matching. Rules can incrementmajor,minor,patch, ornone, and can choose base priority frombranch,sourceBranch,tag, anddefault. - Strategy presets: set
strategytogitflow,github-flow,trunk-based,gitlab-flow, orrelease-train. CustombranchRulesare evaluated before preset rules. - release/X[.Y[.Z]]: branch name is authoritative if it contains a version
(release/2→2.0.0,release/2.1→2.1.0,release/2.1.3→2.1.3).
Release-year names likerelease/R2026-2.0are also authoritative and resolve to26.2.0. If not encoded, the current implementation keeps the base version and appends.build. - hotfix/X[.Y[.Z]]: branch name is authoritative if it contains a version.
If not encoded, the current implementation keeps the base version and appends.build. - bugfix//support/: keep the base version and append
.build. - Source branch detection: for
feature/,bugfix/, andsupport/, the tool attempts to infer the branch point from local and remote refs. If the source branch name carries a supported version, that version is used as the base before applying the branch rule. - Custom branch regex: when
branchRegexmatches, its numeric capture groups are used asmajor.minor.patchbefore falling back to tags or0.1.0. For example,branchRegex: /^(?:hotfix|release)\/R(\d+)-(\d+)\.(\d+)$/turnshotfix/R2026-1.5orrelease/R2026-1.5into2026.1.5.0when no tag exists.
In all cases: bumping major resets minor & patch to
0; bumping minor resets patch to0.
Requirements & CI tips
- Your repo must have tags locally. In CI, make sure to fetch them:
- GitHub Actions
- uses: actions/checkout@v4 with: fetch-depth: 0 fetch-tags: true - run: git fetch --tags --force --prune
- GitHub Actions
- If you’re in a workspace/monorepo, point
--cwd(or pass{ cwd }in code) at the repo root.
Typical workflows
Update package.json to computed version
import fs from "fs";
import path from "path";
import { gitversion } from "gitversionjs";
const info = await gitversion();
const pkgPath = path.resolve("package.json");
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
pkg.version = info.version;
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");Write a public version file for your app
import fs from "fs";
fs.mkdirSync("public", { recursive: true });
fs.writeFileSync(
"public/version.json",
JSON.stringify({ version: info.version }, null, 2)
);Project documentation
Maintainer and implementation notes live in docs/:
docs/architecture.md: runtime flow and module responsibilitiesdocs/versioning-rules.md: exact branch, tag, and build-number behaviordocs/development.md: local setup, validation, and packaging checksdocs/github.md: current GitHub project and release documentation status
The repository also has small context.md files at the root and in important
folders. Those are working notes for future maintenance sessions and should be
kept in sync when behavior changes.
Install options
- Global CLI:
npm i -g gitversionjs - Project dev dep:
Then:npm i -D gitversionjs// package.json { "scripts": { "version:print": "gitversionjs --output json" } }
License
This project is licensed under MIT-0 (MIT No Attribution).
In legal terms: do whatever you want.
License (for humans)
Copyright (c) 2025 Whoever found this
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to do absolutely whatever they want with it.
This includes, but is not limited to:
- using it
- copying it
- modifying it
- merging it
- publishing it
- distributing it
- sublicensing it
- selling it
- embedding it in something cursed
- rewriting it badly
- claiming it was obvious in hindsight
You do NOT need to:
- ask for permission
- credit the author
- send beer (though that would be nice)
- understand how it works
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR SANITY.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, LOSSES, BROKEN BUILDS, BROKEN CI PIPELINES, OR EXISTENTIAL CRISES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
If this software breaks something important, that is unfortunate. If it fixes something important, that was clearly intentional.
Final note
If you have read this far, you are either:
- a lawyer
- a compliance bot
- extremely bored
- or deeply suspicious of joy
Normal people do not read license files. They copy code, run it, and move on with their lives.
