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

semalease

v0.2.2

Published

Semantic version commit message based release utilities. Simple, flexible, designed for monorepo (polyci).

Downloads

1,308

Readme

semalease

Finds the latest git tag matching a pattern, analyzes commits since that tag by conventional commits, calculates next version from commit messages, and writes LATEST_VERSION, NEXT_VERSION, LATEST_INCREMENT, and NEXT_INCREMENT.

Version bump (major/minor/patch) is determined by --major, --minor, --patch regex patterns matched against each commit message. Highest match wins.

Version format

semalease extends semver by using a flexible dotted-numeric pattern: \d+(\.\d+)*. This matches any sequence of integers separated by dots (e.g. 1, 1.0, 1.0.0, 1.2.3.4). The default version pattern parses ?<major>, ?<minor>, ?<patch> with minor and patch optional.

Why this helps:

  • Strict semver – Use 1.0.0-style tags. The default pattern matches standard semver.
  • Pre-release / branch workflows – Add an optional ?<increment> group to the tag pattern. The version stays stable; the increment bumps on each release (e.g. v1.0.0-develop-0.0.1v1.0.0-develop-0.0.2).
  • Monorepos – Use api-v1.0.0, ui-v2.1.0 with pattern ^(\w+)-v(?<version>...) for per-package versions.
  • Custom schemes – Use --version-pattern to parse any dotted-numeric format.

Examples

Basic usage

Write version variables to a file. Uses default tag pattern ^v(?<version>\d+(\.\d+)*)$ (e.g. v1.2.3).

npx semalease --output .env.release

Custom working directory

Run from a subdirectory (e.g. monorepo module). Git operations use --cwd; output path is resolved from the current directory.

npx semalease --cwd modules/my-package --output modules/my-package/semalease.env

Simple semver tags

Default pattern matches tags like v1.0.0, v2.3.1. Commits since the latest tag determine the bump: feat: → minor, fix: → patch, BREAKING CHANGE → major.

npx semalease -o release.env -t '^v(?<version>\d+(\.\d+)*)$'

Branch-based tags with increment

For pre-release or branch workflows, use ?<increment> in the tag pattern. Tags are sorted by version, then increment. The increment is bumped instead of the version.

Example tags: my-module-v1.0.0-develop-0.0.1, my-module-v1.0.0-develop-0.0.2

npx semalease -o semalease.env -t '^my-module-v(?<version>\d+(\.\d+)*)(-develop-(?<increment>\d+(\.\d+)*))?$'

Custom commit patterns

Override which commit messages trigger major/minor/patch bumps. Defaults: feat: → minor, fix:/chore: → patch, BREAKING CHANGE or !: → major.

npx semalease -o .env.release \
  --major '^break:' \
  --minor '^feat:' \
  --patch '^fix:'

Options

| Option | Description | |--------|-------------| | -o, --output | Output file path (required) | | -t, --tag-pattern | Tag regex with ?<version> and optionally ?<increment>. Default: ^v(?<version>\d+(\.\d+)*)$. If ?<increment> present: sorts by version then increment, bumps increment instead of version. | | -v, --version-pattern | Regex to parse version/increment into ?<major>, ?<minor>, ?<patch>. Default: ^(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)$ | | --cwd | Working directory (default: current directory) | | --major | Regex for major bump | | --minor | Regex for minor bump | | --patch | Regex for patch bump |

GitLab CI

Git strategy and depth

semalease uses git tag -l and git log to find tags and analyze commits. In GitLab CI, shallow clones (GIT_DEPTH < full history) can omit tags whose commits were not fetched. Jobs that run semalease should use a full clone so all tags are available.

variables:
  GIT_DEPTH: 0        # Full clone; required for semalease to see all tags
  GIT_STRATEGY: clone # Prefer clone over fetch to avoid stale tag references

If you cannot use a full clone, run git fetch --tags before semalease to pull tags from the remote. Tags pointing to commits outside a shallow fetch may still be missing.

Examples

Minimal release job

Run semalease, source the output, and use the version variables. Requires git for tag/commit analysis.

release:
  stage: release
  image: node:alpine
  before_script:
    - apk add --no-cache git
  script:
    - npx semalease -o semalease.env
    - source semalease.env
    - echo "Next version: $NEXT_VERSION"
    - |
      if [ -n "${NEXT_VERSION:-}" ] && [ "${NEXT_VERSION}" != "${LATEST_VERSION:-}" ]; then
        npm version $NEXT_VERSION --no-git-tag-version
        # git tag, npm publish, etc.
      fi

Monorepo: loop over modules

Use --cwd when packages live in subdirectories. Loop over modules and run semalease for each with a module-specific tag pattern (e.g. api-v1.0.0, ui-v2.1.0).

release:
  stage: release
  image: node:alpine
  before_script:
    - apk add --no-cache git
  script:
    - |
      for MODULE in api ui shared; do
        MODULE_PATH="modules/$MODULE"
        npx semalease --cwd "$MODULE_PATH" --tag-pattern "^${MODULE}-v(?<version>\\d+(\\.\\d+)*)$" -o "$MODULE_PATH/semalease.env"
        if [ -f "$MODULE_PATH/semalease.env" ]; then
          source "$MODULE_PATH/semalease.env"
          echo "$MODULE: LATEST=$LATEST_VERSION NEXT=$NEXT_VERSION"
        fi
      done

Branch-based pre-release (main vs develop)

Use different tag patterns per branch. Main branch: simple v1.0.0. Develop: v1.0.0-develop-0.0.1 with increment.

release:
  stage: release
  image: node:alpine
  before_script:
    - apk add --no-cache git
  script:
    - |
      if [ "$CI_COMMIT_BRANCH" = "main" ]; then
        npx semalease -o semalease.env -t '^v(?<version>\d+(\.\d+)*)$'
      else
        npx semalease -o semalease.env -t '^v(?<version>\d+(\.\d+)*)(-'"$CI_COMMIT_BRANCH"'-(?<increment>\d+(\.\d+)*))?$'
      fi
    - source semalease.env
    - echo "NEXT_VERSION=$NEXT_VERSION NEXT_INCREMENT=$NEXT_INCREMENT"