
Security News
Axios Supply Chain Attack Reaches OpenAI macOS Signing Pipeline, Forces Certificate Rotation
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.
Next-generation version management for Node.js - beautiful CLI, automatic changelogs, branch protection, monorepo support, and more. Zero dependencies.
Next-generation version management for Node.js with beautiful CLI, comprehensive automation, and zero dependencies.
🌐 Website • 📖 Documentation • 📦 NPM • 🚀 Releases
Latest Release: v3.0.6 introduces standalone compiled binaries - install CitrusVer without Node.js or npm!
curl -fsSL https://citrusver.jakerains.com/install.sh | bashCitrusVer 3.0 introduced a fundamental redesign with a simpler, more predictable default behavior:
Default Behavior is Now Version-Only
citrusver patch/minor/major now only updates package.jsonWhy This Change?
Choose your workflow with intuitive flags:
citrusver patch - Just bump the version (fast & simple)citrusver patch --commit - Bump + create commitcitrusver patch --tag - Bump + commit + tagcitrusver patch --push - Bump + commit + pushcitrusver patch --full - Complete workflow (v2 behavior)citrusver patch --quiet - Minimal output
🚀 12 Major New Features • 🎨 Beautiful CLI • ⚙️ Highly Configurable • 📦 Zero Dependencies
Transform your release workflow with intelligent version management, automatic changelogs, branch protection, and more!
Quick Links:
Quick Install:
# Compiled binary (recommended - no Node.js required!)
curl -fsSL https://citrusver.jakerains.com/install.sh | bash
# NPM (also available)
npx citrusver patch
.citrusver.jsonFast, standalone installation with zero npm overhead:
curl -fsSL https://citrusver.jakerains.com/install.sh | bash
This installs a compiled binary to /usr/local/bin/citrusver. No Node.js modules, instant startup!
Available for:
Binary sizes:
npx citrusver patch
npx citrusver minor
npx citrusver major
npm install --save-dev citrusver
Then add to your package.json scripts:
{
"scripts": {
"version:patch": "citrusver patch",
"version:minor": "citrusver minor",
"version:major": "citrusver major"
}
}
npm install -g citrusver
# Just bump the version - fast and simple!
npx citrusver patch # 1.0.0 → 1.0.1
npx citrusver minor # 1.0.0 → 1.1.0
npx citrusver major # 1.0.0 → 2.0.0
# Prerelease versions
npx citrusver alpha # 1.0.0 → 1.0.1-alpha.0
npx citrusver beta # 1.0.0 → 1.0.1-beta.0
# That's it! Only package.json is updated.
# Bump + create commit
npx citrusver patch --commit
# Bump + commit + tag
npx citrusver patch --tag
# Bump + commit + push to remote
npx citrusver patch --push
# Complete workflow (all features)
npx citrusver patch --full
# See what will happen without making changes
npx citrusver patch --dry-run
npx citrusver minor --commit --dry-run
# Minimal output - just the version number
npx citrusver patch --quiet
# Output: 1.0.1
# Bump patch version (1.0.0 → 1.0.1)
citrusver patch
# Bump minor version (1.0.0 → 1.1.0)
citrusver minor
# Bump major version (1.0.0 → 2.0.0)
citrusver major
# Create alpha prerelease (1.0.0 → 1.0.1-alpha.0)
citrusver alpha
# Create beta prerelease (1.0.0 → 1.0.1-beta.0)
citrusver beta
# Custom prerelease identifier
citrusver prerelease --preid rc
Default Behavior (No Flags):
package.json versionpackage-lock.json version (if exists)With --commit Flag:
With --tag Flag:
With --push Flag:
With --full Flag:
You can combine flags for custom workflows:
# Version only
citrusver patch
# Version + commit
citrusver patch --commit
# Version + commit + tag
citrusver patch --tag
# Version + commit + push (adds tag if autoTag is true)
citrusver patch --push
# Everything
citrusver patch --full
# Any combination with dry-run
citrusver patch --tag --dry-run
# Any combination in quiet mode
citrusver patch --commit --quiet
Create a .citrusver.json file in your project root:
{
"messageStyle": "interactive",
"autoTag": true,
"autoPush": false,
"preVersion": "npm test",
"postVersion": "npm run build",
"commitTemplate": "Release: {{message}}\n\nVersion: {{version}}"
}
| Option | Type | Default | Description |
|---|---|---|---|
messageStyle | string | "interactive" | How to handle commit messages |
autoTag | boolean | true | Create git tags automatically |
autoPush | boolean | false | Push to remote after versioning |
preVersion | string | null | Command to run before version bump |
postVersion | string | null | Command to run after version bump |
commitTemplate | string | null | Custom commit message template |
confirmRelease | boolean | false | Show confirmation before applying |
changelog | boolean | false | Generate CHANGELOG.md automatically |
| Option | Type | Default | Description |
|---|---|---|---|
conventionalCommits | boolean | false | Enable conventional commit workflow |
versionStrategy | string | "semver" | Version strategy: semver, date, custom |
plugins | array | [] | List of plugins to load |
branch.protected | array | ["main", "master"] | Protected branch names |
branch.allowForce | boolean | false | Allow force flag on protected branches |
monorepo.enabled | boolean | false | Enable monorepo support |
monorepo.packages | string | "packages/*" | Workspace packages pattern |
monorepo.independent | boolean | false | Independent package versioning |
npm.publish | boolean | false | Auto-publish to npm |
npm.access | string | "public" | NPM package access level |
npm.checkRegistry | boolean | false | Check if version exists on npm |
Use {{message}} and {{version}} placeholders:
{
"commitTemplate": "🚀 Release {{version}}: {{message}}"
}
Preview what will happen without making changes:
citrusver patch --dry-run
Automatically update CHANGELOG.md:
citrusver minor --changelog
Use the enhanced interactive mode:
{
"conventionalCommits": true
}
Create alpha, beta, or custom prerelease versions:
Quick Commands:
# Create alpha version
citrusver alpha
# 1.0.0 → 1.0.1-alpha.0
# Create beta version
citrusver beta
# 1.0.0 → 1.0.1-beta.0
# Increment existing prerelease
citrusver alpha
# 1.0.1-alpha.0 → 1.0.1-alpha.1
Advanced Usage:
# Custom prerelease identifier (rc, canary, etc.)
citrusver prerelease --preid rc
# 1.0.0 → 1.0.1-rc.0
# Combine with git operations
citrusver alpha --commit # Alpha + commit
citrusver beta --tag # Beta + commit + tag
citrusver alpha --push # Alpha + commit + push
Version Progression:
1.0.0 → citrusver alpha → 1.0.1-alpha.0
→ citrusver alpha → 1.0.1-alpha.1
→ citrusver beta → 1.0.1-beta.0
→ citrusver beta → 1.0.1-beta.1
→ citrusver patch → 1.0.1
Quick setup with templates:
# Interactive setup
citrusver init
# Use a template
citrusver init --template conventional
citrusver init --template monorepo
Running citrusver init also adds the CLI to your project's devDependencies, ensuring teammates pick it up on install.
Configure for workspaces:
{
"monorepo": {
"enabled": true,
"packages": "packages/*",
"independent": false
}
}
Prevent releases from wrong branches:
{
"branch": {
"protected": ["main", "master"],
"releaseBranches": ["main", "release/*"]
}
}
# Fast and simple - just bump the version
citrusver patch
# Done! Manual commit later if needed
# Bump version and create release commit
citrusver minor --tag
# Add custom message when prompted
git push origin main --tags
# Quiet mode for scripts
VERSION=$(citrusver patch --quiet)
echo "Bumped to $VERSION"
# Or with full automation
citrusver patch --push
# Develop your feature...
# When ready:
citrusver minor --commit
# Type: "Add user authentication system"
# Commit created automatically
git push
# v2.x behavior (default created commit + tag)
# Now use --tag flag for same behavior:
citrusver patch --tag
# Or use --full for complete v2.x experience:
citrusver patch --full
{
"preVersion": "npm test && npm run lint",
"postVersion": "npm run build",
"autoPush": true
}
Then use:
citrusver patch --commit # Hooks run with git operation flags
CitrusVer provides beautiful visual feedback with a clean, modern CLI:
╭──────────────────────────────────────────────╮
│ 🍋 CitrusVer · PATCH RELEASE │
├──────────────────────────────────────────────┤
│ Current 1.0.0 │
│ Next 1.0.1 │
│ │
│ Fresh-squeezed semver for your repo │
╰──────────────────────────────────────────────╯
🍋 Bumping patch version...
========================================
✅ VERSION BUMPED! ✅
========================================
New Version: v1.0.1
package.json has been updated
----------------------------------------
🍋 Fresh release squeezed! 🍋
╭──────────────────────────────────────────────╮
│ 🍋 CitrusVer · MINOR RELEASE │
├──────────────────────────────────────────────┤
│ Current 1.0.0 │
│ Next 1.1.0 │
│ │
│ Fresh-squeezed semver for your repo │
╰──────────────────────────────────────────────╯
› Commit message for v1.1.0 (Enter to skip · Esc cancels): Add user authentication
🍋 Bumping minor version...
📦 Staging changes...
💾 Creating version commit...
🏷️ Creating version tag...
========================================
✅ VERSION BUMPED! ✅
========================================
New Version: v1.1.0
Changes have been committed
Git tag has been created
----------------------------------------
Next Step:
git push origin HEAD --tags
🍋 Fresh release squeezed! 🍋
$ citrusver patch --quiet
1.0.1
Run commands before and after versioning:
{
"preVersion": "npm test",
"postVersion": "npm run build && npm run docs"
}
Automatically push to remote after versioning:
{
"autoPush": true
}
Create project-specific commit formats:
{
"commitTemplate": "[{{version}}] {{message}}"
}
CitrusVer supports custom plugins to extend functionality:
// .citrusver/plugins/my-plugin.js
class MyPlugin {
constructor() {
this.name = 'my-plugin';
this.version = '1.0.0';
this.hooks = {
'pre-version': this.preVersion.bind(this),
'post-version': this.postVersion.bind(this)
};
}
async preVersion(context) {
console.log('Running pre-version hook');
// Your logic here
}
async postVersion(context) {
console.log('Version bumped to:', context.version);
// Your logic here
}
}
module.exports = MyPlugin;
{
"plugins": ["./citrusver/plugins/my-plugin"]
}
pre-version - Before version bumppost-version - After version bumppre-commit - Before creating commitpost-commit - After creating commitpre-tag - Before creating tagpost-tag - After creating tagchangelog-generate - During changelog generationversion-calculate - Custom version calculationVisit citrusver.jakerains.com for:
The website is built with Next.js and hosted on Vercel, featuring:
Contributions are welcome! Please feel free to submit a Pull Request.
git checkout -b feature/AmazingFeature)git commit -m 'Add some AmazingFeature')git push origin feature/AmazingFeature)MIT © Jake Rains
npm version but with better UX
Made with 🍋 by Jake Rains
Website •
NPM •
GitHub
FAQs
Next-generation version management for Node.js - beautiful CLI, automatic changelogs, branch protection, monorepo support, and more. Zero dependencies.
We found that citrusver demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.

Security News
Open source is under attack because of how much value it creates. It has been the foundation of every major software innovation for the last three decades. This is not the time to walk away from it.

Security News
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.