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

@utensilia/compare-versions

v1.0.0

Published

Strict Semantic Versioning 2.0.0 comparison and npm-style range matching

Readme

@utensilia/compare-versions

npm types License: MIT

Strict Semantic Versioning 2.0.0 comparison and npm-style range matching, with no dependencies.

  • Strict versions — a version is always MAJOR.MINOR.PATCH; v1.2.3, 1.2 or 01.2.3 are errors, not guesses
  • npm ranges — ^, ~, x and * wildcards, partial versions, hyphen ranges and ||, with the same results as the semver package used by npm
  • Pre-release aware — pre-releases follow the SemVer precedence rules and npm's range rules
  • Typed and small — TypeScript definitions, ES modules, tree-shakeable

Installation

npm install @utensilia/compare-versions

Usage

import { compare, compareVersions, satisfies, validate, validateRange } from '@utensilia/compare-versions';

compareVersions('1.10.0', '1.9.0');           // 1
compare('2.0.0-rc.1', '2.0.0', '<');          // true

satisfies('1.4.2', '^1.2.0');                 // true
satisfies('1.2.5', '1.2');                    // true
satisfies('2.0.0-beta.1', '^1.2.0 || >=2');   // false

validate('v1.2.3');                           // false
validateRange('~1.2');                        // true

API

compareVersions(version1, version2)

Returns 1 when version1 is greater, -1 when it is lower and 0 when both have the same precedence. Build metadata is ignored.

Throws TypeError: Invalid version string: "<version>" for the first argument that is not a valid version.

compare(version1, version2, operator)

Returns whether version1 <operator> version2 holds. operator is one of '>', '>=', '=', '<=', '<'.

Throws TypeError for an unknown operator or an invalid version.

satisfies(version, range)

Returns whether version is within range.

Throws TypeError for an invalid version or TypeError: Invalid range: "<range>" for an invalid range.

validate(version)

Returns whether version is a valid Semantic Versioning 2.0.0 version within the limits. Never throws.

validateRange(range)

Returns whether range is valid range syntax. Never throws.

Types

type Comparison = -1 | 0 | 1;
type CompareOperator = '>' | '>=' | '=' | '<=' | '<';

Precedence

| Rule | Example | |---|---| | MAJOR, MINOR and PATCH are compared numerically | 1.10.0 > 1.9.0 | | A release is greater than its pre-releases | 1.0.0 > 1.0.0-rc.1 | | Numeric pre-release identifiers are compared numerically | 1.0.0-beta.11 > 1.0.0-beta.2 | | Alphanumeric identifiers are compared in ASCII order | 1.0.0-beta > 1.0.0-alpha | | Numeric identifiers are lower than alphanumeric ones | 1.0.0-alpha > 1.0.0-1 | | More identifiers win when the shared ones are equal | 1.0.0-alpha.1 > 1.0.0-alpha | | Build metadata is ignored | 1.0.0+1 = 1.0.0+2 |

Range syntax

Versions are always complete. Partial versions such as 1 or 1.2 are range shorthand only: satisfies('1.2.5', '1.2') is true, while satisfies('1.2', '^1.0.0') throws.

| Range | Matches | Same as | |---|---|---| | 1.2.3, =1.2.3 | exactly that version | =1.2.3 | | >1.2.3, >=1.2.3, <1.2.3, <=1.2.3 | by comparison | | | *, x, empty string | every release | >=0.0.0 | | 1, 1.x | any 1.*.* | >=1.0.0 <2.0.0-0 | | 1.2, 1.2.x | any 1.2.* | >=1.2.0 <1.3.0-0 | | >1, <=1.2 | partial comparisons | >=2.0.0, <1.3.0-0 | | ~1.2.3 | patch updates | >=1.2.3 <1.3.0-0 | | ^1.2.3 | minor and patch updates | >=1.2.3 <2.0.0-0 | | ^0.2.3 | patch updates below 1.0.0 | >=0.2.3 <0.3.0-0 | | ^0.0.3 | that version only | >=0.0.3 <0.0.4-0 | | 1.2.3 - 2.3.4 | inclusive interval | >=1.2.3 <=2.3.4 | | >=1.2.7 <1.3.0 | all conditions (space) | | | ^1.2.3 \|\| ^2.0.0 | any alternative | |

Pre-releases

A pre-release version matches only a range that names a pre-release of the same MAJOR.MINOR.PATCH, as in npm:

| Call | Result | |---|---| | satisfies('1.2.3-beta.2', '^1.2.3-beta.1') | true | | satisfies('1.3.0-beta', '^1.2.3') | false | | satisfies('2.0.0-rc.1', '*') | false |

Limits

MAJOR, MINOR and PATCH cannot exceed Number.MAX_SAFE_INTEGER (253 − 1), in a version or in any bound a range expands to. 9007199254740991.0.0 is valid; <=9007199254740991 is not, because it expands to <9007199254740992.0.0-0. The semver package has the same limit.

Differences from semver

Results for valid versions and ranges are the same as those of the semver package; the test suite compares both on generated inputs. Invalid input is treated differently:

| Input | semver | @utensilia/compare-versions | |---|---|---| | v1.2.3 or 1.2.3 as a version | accepted, prefix and spaces dropped | invalid | | v1.2.3, =v1.2.3 or ~>1.2.3 in a range | accepted | invalid | | pre-release or build after a partial version, as in 1.2.x-beta or 1.2+build | accepted, qualifier dropped | invalid | | invalid version or range in satisfies | returns false | throws TypeError | | version longer than 256 characters | invalid | valid | | includePrerelease option | available | not available |

Requirements

Any environment with ES2022 and ES modules: a current browser or a maintained Node.js version.

License

MIT