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

package-versioner

v0.9.3

Published

A lightweight yet powerful CLI tool for automated semantic versioning based on Git history and conventional commits.

Readme

package-versioner

Features

  • Automatically determines version bumps based on commit history (using conventional commits)
  • Supports both single package projects and monorepos with minimal configuration
  • Support for both npm (package.json) and Rust (Cargo.toml) projects
  • Flexible versioning strategies (e.g., based on commit types, branch patterns)
  • Integrates with conventional commits presets
  • Customizable through a version.config.json file or CLI options
  • Automatically updates package.json or Cargo.toml version
  • Creates appropriate Git tags for releases
  • Automatically generates and maintains changelogs in Keep a Changelog or Angular format
  • Integrates commit messages, breaking changes, and issue references into well-structured changelogs
  • CI/CD friendly with JSON output support

Supporting JavaScript and Rust Projects

package-versioner provides version management for both JavaScript/TypeScript (via package.json) and Rust (via Cargo.toml) projects:

  • JavaScript/TypeScript: Automatically detects and updates version in package.json files
  • Rust: Detects and updates version in Cargo.toml files using the same versioning strategies
  • Mixed Projects: Supports repositories containing both package.json and Cargo.toml files

When run, the tool will automatically discover and update the appropriate manifest file based on the project structure.

Usage

package-versioner is designed to be run directly using your preferred package manager's execution command, without needing global installation.

# Determine bump based on conventional commits since last tag
npx package-versioner

# Using pnpm
pnpm dlx package-versioner

# Using yarn
yarn dlx package-versioner

# Specify a bump type explicitly
npx package-versioner --bump minor

# Create a prerelease (e.g., alpha)
npx package-versioner --bump patch --prerelease alpha

# Target specific packages (only in async/independent mode, comma-separated)
npx package-versioner -t @scope/package-a,@scope/package-b

# Run from a different directory
npx package-versioner --project-dir /path/to/project

# Perform a dry run: calculates version, logs actions, but makes no file changes or Git commits/tags
npx package-versioner --dry-run

# Only use reachable tags (Git-semantic mode, no fallback to unreachable tags)
npx package-versioner --strict-reachable

# Output results as JSON (useful for CI/CD scripts)
npx package-versioner --json

# Combine with dry-run for CI planning
npx package-versioner --dry-run --json

Note on Targeting: Using the -t flag creates package-specific tags (e.g., @scope/[email protected]) but not a global tag (like v1.2.0). If needed, create the global tag manually in your CI/CD script after this command.

Git Tag Reachability

By default, package-versioner intelligently handles Git tag reachability to provide the best user experience:

  • Default behaviour: Uses reachable tags when available, but falls back to the latest repository tag if needed (common in feature branches)
  • Strict mode (--strict-reachable): Only uses tags reachable from the current commit, following strict Git semantics

This is particularly useful when working on feature branches that have diverged from the main branch where newer tags exist. The tool will automatically detect the Git context and provide helpful guidance:

# On a feature branch with unreachable tags
npx package-versioner --dry-run
# Output: "No tags reachable from current branch 'feature-x'. Using latest repository tag v1.2.3 as version base."
# Tip: Consider 'git merge main' or 'git rebase main' to include tag history in your branch.

# Force strict Git semantics
npx package-versioner --dry-run --strict-reachable
# Output: Uses only reachable tags, may result in "No reachable tags found"

JSON Output

When using the --json flag, normal console output is suppressed and the tool outputs a structured JSON object that includes information about the versioning operation.

{
  "dryRun": true,
  "updates": [
    {
      "packageName": "@scope/package-a",
      "newVersion": "1.2.3",
      "filePath": "/path/to/package.json"
    }
  ],
  "commitMessage": "chore(release): v1.2.3",
  "tags": [
    "v@scope/[email protected]"
  ]
}

For detailed examples of how to use this in CI/CD pipelines, see CI/CD Integration.

Configuration

Customize behaviour by creating a version.config.json file in your project root:

{
  "preset": "angular",
  "versionPrefix": "v",
  "tagTemplate": "${packageName}@${prefix}${version}",
  "packageSpecificTags": true,
  "commitMessage": "chore: release ${packageName}@${version} [skip ci]",
  "updateChangelog": true,
  "changelogFormat": "keep-a-changelog",
  "strictReachable": false,
  "sync": true,
  "skip": [
    "docs",
    "e2e"
  ],
  "packages": ["@mycompany/*"],
  "mainPackage": "primary-package",
  "cargo": {
    "enabled": true,
    "paths": ["src/", "crates/"]
  }
}

Configuration Options

General Options (All Projects)

  • preset: Conventional commits preset to use for version calculation (default: "angular")
  • versionPrefix: Prefix for version numbers in tags (default: "v")
  • tagTemplate: Template for Git tags (default: "${prefix}${version}")
  • commitMessage: Template for commit messages (default: "chore(release): ${version}")
  • updateChangelog: Whether to automatically update changelogs (default: true)
  • changelogFormat: Format for changelogs - "keep-a-changelog" or "angular" (default: "keep-a-changelog")
  • strictReachable: Only use reachable tags, no fallback to unreachable tags (default: false)
  • prereleaseIdentifier: Identifier for prerelease versions (e.g., "alpha", "beta", "next") used in versions like "1.2.0-alpha.3"
  • cargo: Options for Rust projects:
    • enabled: Whether to handle Cargo.toml files (default: true)
    • paths: Directories to search for Cargo.toml files (optional)

Monorepo-Specific Options

  • sync: Whether all packages should be versioned together (default: true)
  • skip: Array of package names or patterns to exclude from versioning. Supports exact names, scope wildcards, path patterns, and global wildcards (e.g., ["@scope/package-a", "@scope/", "packages/**/"])
  • packages: Array of package names or patterns to target for versioning. Supports exact names, scope wildcards, path patterns and global wildcards (e.g., ["@scope/package-a", "@scope/", ""])
  • mainPackage: Package name whose commit history should drive version determination
  • packageSpecificTags: Whether to enable package-specific tagging behaviour (default: false)
  • updateInternalDependencies: How to update internal dependencies ("patch", "minor", "major", or "inherit")

For more details on CI/CD integration and advanced usage, see CI/CD Integration.

Package Targeting

The packages configuration option controls which packages are processed for versioning. It supports several pattern types:

Exact Package Names

{
  "packages": ["@mycompany/core", "@mycompany/utils", "standalone-package"]
}

Scope Wildcards

Target all packages within a specific scope:

{
  "packages": ["@mycompany/*"]
}

Path Patterns / Globs

Target all packages in a directory or matching a path pattern:

{
  "packages": ["packages/**/*", "examples/**"]
}

This will match all packages in nested directories under packages/ or examples/.

Global Wildcard

Target all packages in the workspace:

{
  "packages": ["*"]
}

Mixed Patterns

Combine different pattern types:

{
  "packages": ["@mycompany/*", "@utils/logger", "legacy-package", "packages/**/*"]
}

Behaviour:

  • When packages is specified, only packages matching those patterns will be processed
  • When packages is empty or not specified, all workspace packages will be processed
  • The skip option can exclude specific packages from the selected set

Note: Your workspace configuration (pnpm-workspace.yaml, package.json workspaces, etc.) determines which packages are available, but the packages option directly controls which ones get versioned.

Package-Specific Tagging

The packageSpecificTags option controls whether the tool creates and searches for package-specific Git tags:

  • When false (default): Creates global tags like v1.2.3 and searches for the latest global tag
  • When true: Creates package-specific tags like @scope/[email protected] and searches for package-specific tags

This option works in conjunction with tagTemplate to control tag formatting. The tagTemplate is used for all tag creation, with the packageSpecificTags boolean controlling whether the ${packageName} variable is populated:

  • When packageSpecificTags is false: The ${packageName} variable is empty, so templates should use ${prefix}${version}
  • When packageSpecificTags is true: The ${packageName} variable contains the package name

Examples:

For single-package repositories or sync monorepos:

{
  "packageSpecificTags": true,
  "tagTemplate": "${packageName}@${prefix}${version}"
}

Creates tags like [email protected]

For global versioning:

{
  "packageSpecificTags": false,
  "tagTemplate": "${prefix}${version}"
}

Creates tags like v1.2.3

Important Notes:

  • In sync mode with a single package, packageSpecificTags: true will use the package name even though all packages are versioned together
  • In sync mode with multiple packages, package names are not used regardless of the setting
  • In async mode, each package gets its own tag when packageSpecificTags is enabled

With package-specific tagging enabled, the tool will:

  1. Look for existing tags matching the configured pattern for each package
  2. Create new tags using the same pattern when releasing
  3. Fall back to global tag lookup if no package-specific tags are found

How Versioning Works

package-versioner determines the next version based on your configuration (version.config.json). The two main approaches are:

  1. Conventional Commits: Analyzes commit messages (like feat:, fix:, BREAKING CHANGE:) since the last tag.
  2. Branch Pattern: Determines the bump based on the current or recently merged branch name matching predefined patterns.

For a detailed explanation of these concepts and monorepo modes (Sync vs. Async), see Versioning Strategies and Concepts.

Documentation

For more details on available CLI options, run:

npx package-versioner --help

Acknowledgements

This project was originally forked from and inspired by jucian0/turbo-version. We appreciate the foundational work done by the original authors.

License

MIT