npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@arcmantle/prospector

v1.1.2

Published

Automatic semantic versioning from git history for trunk-based development

Readme

Prospector

Semantic versioning made simple. Calculate versions automatically from your git history using trunk-based development.

What is Prospector?

Prospector is a tool that generates semantic versions (semver) for your project based on git commits. Instead of manually updating version numbers, Prospector reads your git history and commit messages to calculate the current version automatically.

Perfect for:

  • Trunk-based development workflows
  • Automated CI/CD pipelines
  • Projects that want automatic versioning without manual intervention
  • Teams that need consistent versioning across repositories

Quick Start

# Install
pnpm add -D @arcmantle/prospector

# Get current version
prospector
# Output: 1.2.5

# See what's next
prospector --suggest minor
# Output: 1.3.0

Using in GitHub Actions

The primary way to use Prospector is in CI/CD pipelines. Add it to your workflow to automatically version your packages:

name: Publish Package

on:
  push:
    branches: [main]

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Required: fetch all history for version calculation

      - uses: actions/setup-node@v4
        with:
          node-version: 24
          registry-url: https://registry.npmjs.org/

      # Calculate version using Prospector
      - name: Calculate version
        id: version
        uses: arcmantle/prospector@v1
        with:
          dir: '.'  # Optional: defaults to repository root

      # Use the calculated version
      - name: Set package version
        run: |
          echo "Setting version to ${{ steps.version.outputs.version }}"
          npm version ${{ steps.version.outputs.version }} --no-git-tag-version

      - name: Publish to NPM
        run: npm publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

GitHub Action Inputs

| Input | Description | Default | | ------- | ------------- | --------- | | dir | Repository directory path | '.' | | branch | Main branch name(s) | 'main' (also recognizes 'master') | | prefix | Version tag prefix | 'v' | | no-commit-bumps | Disable commit message bumping | false |

GitHub Action Outputs

| Output | Description | | -------- | ------------- | | version | The calculated semantic version (e.g., 1.2.5) | | branch | Current branch name | | is-main-branch | 'true' if on main branch, 'false' otherwise | | commits-since-tag | Number of commits since last version tag |

Example: Conditional Publishing

Only publish on main branch with new commits:

- name: Calculate version
  id: version
  uses: arcmantle/prospector@v1

- name: Publish to NPM
  if: steps.version.outputs.is-main-branch == 'true' && steps.version.outputs.commits-since-tag != '0'
  run: npm publish
  env:
    NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

Key Features

  • 🚀 Smart Version Calculation: Automatically determines versions from git history
  • 💬 Commit Message Bumps: Use [major], [minor], [patch] in commit messages for explicit version control
  • 🏷️ Tag-Based Releases: Create git tags for official version markers
  • 🌿 Branch-Aware: Different versioning for main branch vs feature branches
  • ⚡ Lightning Fast: Optimized for repositories with millions of commits
  • 🔧 Flexible: CLI tool or programmatic API
  • 📦 Zero Config: Works out of the box with sensible defaults
  • ⚙️ GitHub Action: Use in CI/CD pipelines (see GitHub Action docs)

How It Works

Three Simple Rules

  1. On main branch: Version increments based on commits and tags
  2. On feature branches: Version gets a prerelease suffix (e.g., 1.2.3-feature.5)
  3. Git tags set versions: Create tags like v1.0.0 to mark releases

Example

# Start: No tags, 10 commits on main
prospector → 0.0.10

# Tag a release
git tag v1.0.0

# Make 3 more commits
prospector → 1.0.3

# Create feature branch with 2 commits
git checkout -b feature/awesome
prospector → 1.0.1-feature-awesome.2

# Merge back to main
git checkout main
git merge feature/awesome
prospector → 1.0.4

Installation

# npm
npm install -D @arcmantle/prospector

# pnpm
pnpm add -D @arcmantle/prospector

# yarn
yarn add -D @arcmantle/prospector

Or use as a GitHub Action - see GitHub Action docs for details.

Usage

Command Line Interface

# Get the current version
prospector

# Output as JSON
prospector --json

# Show detailed information
prospector --detailed

# Suggest next version for a release
prospector --suggest minor
prospector --suggest major

# Use custom repository path
prospector --dir /path/to/repo

# Use custom branch name and tag prefix
prospector --branch master --prefix version-

# Default supports both 'main' and 'master' automatically
# No need to specify --branch unless using a different name

CLI Options

  • -h, --help - Show help message
  • -d, --dir <path> - Git repository path (default: current directory)
  • -b, --branch <name> - Main/trunk branch name (default: both main and master are recognized)
  • -p, --prefix <prefix> - Version tag prefix (default: v)
  • --json - Output as JSON
  • --detailed - Output detailed information
  • --suggest <type> - Suggest next version (major, minor, or patch)
  • --no-commit-bumps - Disable commit message based version bumping

Programmatic API

import { calculateVersion, suggestVersionBump } from '@arcmantle/prospector';

// Get current version
const info = await calculateVersion({
  cwd: '/path/to/repo',
  tagPrefix: 'v'
});

console.log(info.version);      // "1.2.5"
console.log(info.commitBumps);  // { major: 0, minor: 2, patch: 1, explicitVersion: null }

// Suggest next version
const next = await suggestVersionBump('minor');
console.log(next); // "1.3.0"

Configuration Options

await calculateVersion({
  // Repository path (default: current directory)
  cwd: '/path/to/repo',

  // Main branch names (default: ['main', 'master'])
  mainBranch: 'develop',
  // Or multiple: mainBranch: ['main', 'master', 'trunk'],

  // Tag prefix (default: 'v')
  tagPrefix: 'version-',

  // Enable commit message bumping (default: true)
  enableCommitBumps: true,

  // Custom commit patterns
  commitBumpPatterns: {
    major: /BREAKING|!:/i,
    minor: /feature:|feat:/i,
    patch: /fix:|bugfix:/i
  },

  // Progress callback
  onProgress: (msg) => console.log(msg)
});

Versioning Behavior

Main Branch (Trunk)

On your main branch, Prospector uses commit messages to determine version bumps:

Commit Message Markers

Add these markers to your commit messages for explicit version control:

| Marker | Effect | Example | |-------------------|------------------------------------|--------------------------------------------------------| | [major] | Bump major version (2.0.0 → 3.0.0) | git commit -m "[major] Breaking API changes" | | [minor] | Bump minor version (1.2.0 → 1.3.0) | git commit -m "[minor] Add new feature" | | [patch] | Bump patch version (1.2.3 → 1.2.4) | git commit -m "[patch] Fix bug" | | [version:x.y.z] | Set exact version | git commit -m "[version:2.5.0] Release 2.5.0" | | [v:x.y.z] | Set exact version (short) | git commit -m "[v:1.0.0] Initial release" |

How Bumps Work

  • Explicit versions ([version:x.y.z]) take absolute precedence
  • Multiple bump indicators accumulate (e.g., 3 [minor] = +3 to minor version)
  • When major bumps, minor and patch reset to 0
  • When minor bumps, patch resets to 0
  • If no explicit bumps found, falls back to commit count

Optimized Scanning (Default)

Prospector is extremely fast even with millions of commits. It uses git's internal indexes to find only commits with bump markers:

Why it's fast:

  • Only fetches commits containing [major], [minor], [patch], or [version:x.y.z]
  • Uses git log --grep (built-in git optimization)
  • Early stops when explicit version found
  • Typical repositories: <1% of commits have markers

Performance examples:

  • 100K commits, 50 with markers → ~0.2s, ~500KB memory
  • 1M commits, 100 with markers → ~0.3s, ~1MB memory
  • 10M commits, 200 with markers → ~0.5s, ~2MB memory

No configuration needed - it just works fast out of the box!

Legacy Scan Limit (Optional)

For edge cases or specific performance requirements, you can enable a scan limit:

// Only if you experience performance issues
calculateVersion({ maxCommitScan: 1000 })

When maxCommitScan is set, Prospector falls back to the legacy scanning mode that fetches all commits up to the limit. This is generally not needed with the optimized approach.

Tagging Best Practices

Use git tags to mark official releases:

# Work with commit markers
git commit -m "[minor] Add feature A"
git commit -m "[patch] Fix bug"
git commit -m "[minor] Add feature B"

# Mark official release
git tag v1.5.0
git push --tags

# Continue development
git commit -m "[patch] Quick fix"
prospector → 1.5.1

Why tag?

  • Tags mark stable release points
  • Makes version history clear
  • Allows easy rollback to specific versions
  • Prevents hundreds of bump markers from accumulating

Feature Branches

Feature branches automatically get prerelease versions:

Format: {base_version}-{branch_name}.{commit_count}

Example:

# On main: v1.2.0 exists
git checkout -b feature/awesome-thing

# Make 3 commits
prospector → 1.2.1-feature-awesome-thing.3

How it works:

  1. Find last version tag (v1.2.0)
  2. Increment patch by 1 (1.2.1)
  3. Add branch name (sanitized) and commit count as prerelease

This makes it clear the version is:

  • Not an official release
  • Based on version 1.2.0
  • From the "feature-awesome-thing" branch
  • 3 commits ahead

No Tags (Initial State)

When no git tags exist:

  • Main branch: 0.0.{total_commits}
    • Example: 15 commits → 0.0.15
  • Feature branch: 0.0.1-{branch_name}.{total_commits}
    • Example: 8 commits on feature/init0.0.1-feature-init.8

Create your first tag when ready to release:

git tag v1.0.0
git push --tags

Advanced Usage

Disable Commit Bumps (Faster)

For maximum speed, disable commit message scanning:

# CLI
prospector --no-commit-bumps

# API
await calculateVersion({ enableCommitBumps: false })

This uses only commit count, no message parsing. Version is simply {tag} + {commit_count}.

Custom Commit Patterns

Match your team's commit conventions:

await calculateVersion({
  commitBumpPatterns: {
    major: /BREAKING CHANGE|!:/i,
    minor: /^feat:/i,
    patch: /^fix:/i
  }
});

Now commits like feat: add dashboard will bump minor version.

Legacy Scan Limit

If you experience issues (very rare), you can limit commit scanning:

await calculateVersion({
  maxCommitScan: 1000  // Only scan last 1000 commits
})

Note: This is rarely needed. The default optimized mode handles millions of commits efficiently.

API Reference

calculateVersion(options?)

Calculates the current version based on git history.

Parameters:

  • options.cwd - Repository path (default: '.')
  • options.mainBranch - Main/trunk branch name(s). Can be a string or array of strings (default: ['main', 'master'] - both are recognized as trunk branches)
  • options.tagPrefix - Tag prefix (default: 'v')
  • options.enableCommitBumps - Enable commit message bumping (default: true)
  • options.maxCommitScan - Optional limit on commits to scan. Only set this if you experience performance issues. When undefined (default), uses optimized git grep scanning with no limit.
  • options.commitBumpPatterns - Custom regex patterns for detecting bumps

Returns: VersionInfo object with:

  • version - The calculated version string
  • branch - Current branch name
  • isMainBranch - Whether on main branch
  • commitsSinceTag - Number of commits since last tag
  • lastTag - Last version tag info (or null)
  • currentCommit - Current commit hash
  • commitBumps - Object with { major, minor, patch, explicitVersion } counts from commit messages

suggestVersionBump(bumpType, options?)

Suggests the next version for a given bump type.

Parameters:

  • bumpType - 'major', 'minor', or 'patch'
  • options - Same as calculateVersion

Returns: Version string (e.g., '2.0.0')

Performance

Prospector is extremely fast even with millions of commits:

Why It's Fast

  • Optimized git operations: Uses git log --grep to scan only commits with bump markers
  • Typical case: <1% of commits have version markers, so we only process <1%
  • Early termination: Stops when explicit version found
  • Smart counting: Uses git rev-list --count (O(1) operation)

Performance Data

|Repository Size|Commits with Bumps|Time |Memory| |---------------|------------------|------|------| |1K commits |20 |< 0.1s|< 1MB | |10K commits |50 |< 0.2s|< 1MB | |100K commits |100 |< 0.3s|< 2MB | |1M commits |200 |< 0.5s|< 3MB | |10M commits |500 |< 1s |< 5MB |

With --no-commit-bumps: All sizes run in < 0.1s.

Quick Reference

Commit Marker Syntax

# Major version bump (1.0.0 → 2.0.0)
git commit -m "[major] Breaking API changes"

# Minor version bump (1.0.0 → 1.1.0)
git commit -m "[minor] New reporting feature"

# Patch version bump (1.0.0 → 1.0.1)
git commit -m "[patch] Fix bug in login"

# Set exact version
git commit -m "[version:2.5.0] Release version 2.5.0"
git commit -m "[v:1.3.7] Align with upstream"

# No explicit bump (uses commit count for patch)
git commit -m "Update README"

See docs/COMMIT_SYNTAX.md for more details on commit message patterns.

Common CLI Commands

# Get current version
prospector

# Show detailed information including commit bumps
prospector --detailed

# Disable commit message bumping
prospector --no-commit-bumps

# Suggest next minor release
prospector --suggest minor

# Use in different directory
prospector --dir /path/to/repo

License

MIT