Semantic Versioning done right — parse, compare, sort and range-match versions in ~2 KB, with zero dependencies.
Does 1.2.3-beta.11 come before or after 1.2.3-beta.2? Does 1.2.3-rc.1
satisfy ^1.0.0? These are spec questions with exact answers — and exactly the
kind of fiddly rule that's easy to get wrong by hand. verspec implements
SemVer 2.0.0 precisely, including prerelease precedence
and the prerelease-in-range rule.
import { compare, satisfies, sort } from "verspec";
compare("1.2.3-beta.2", "1.2.3-beta.11"); // -1 (numeric identifiers compare numerically)
satisfies("1.2.3", "^1.0.0"); // true
satisfies("1.2.3-rc.1", "^1.0.0"); // false (prereleases don't leak into plain ranges)
sort(["1.10.0", "1.2.0", "1.0.0-rc.1"]); // ["1.0.0-rc.1", "1.2.0", "1.10.0"]- 📏 Spec-accurate. Passes the canonical semver.org precedence chain (
alpha < alpha.1 < alpha.beta < beta < beta.2 < beta.11 < rc.1 < release) and the prerelease-in-range rule that trips up naive comparisons. - 🎯 Full range syntax.
^,~,x-ranges, partials, hyphen ranges (1 - 2), comparator sets (>=1.2 <2), and||unions. - 🪶 ~2 KB gzipped, zero dependencies. A fraction of the size of the classic
semverpackage. - 🧩 Complete toolkit.
parse,valid,compare,eq/gt/lt/…,sort/rsort,satisfies,maxSatisfying/minSatisfying,inc. - 🌍 Runs everywhere. Node 18+, Deno, Bun, Workers and the browser.
- 🛡️ Type-safe. Written in TypeScript, ships full declarations.
npm install verspec
# or: pnpm add verspec / yarn add verspec / bun add verspecShips ESM and CommonJS:
import { satisfies } from "verspec"; // ESM / TypeScript
const { satisfies } = require("verspec"); // CommonJSparse("1.2.3-beta.1+build.5");
// { major: 1, minor: 2, patch: 3, prerelease: ["beta", 1], build: ["build", "5"] }
valid("v1.2.3"); // "1.2.3"
valid("1.2"); // nullcompare("2.0.0", "1.9.9"); // 1
gt("2.0.0", "1.0.0"); // true
lte("1.0.0-alpha", "1.0.0"); // true
sort(["1.10.0", "1.2.0", "1.1.0"]); // ["1.1.0", "1.2.0", "1.10.0"]
rsort(versions); // descendingsatisfies("1.2.9", "~1.2.3"); // true
satisfies("0.3.0", "^0.2.3"); // false
satisfies("1.2.7", "1.2.x"); // true
satisfies("2.3.4", "1.2.3 - 2.3.4"); // true
satisfies("3.1.0", "^1 || ^3"); // true
maxSatisfying(["1.2.0", "1.2.5", "1.3.0"], "~1.2.0"); // "1.2.5"
validRange(">=1.0.0 <2.0.0 || 3.x"); // trueBy default, a prerelease only satisfies a range that explicitly targets the same
major.minor.patch with a prerelease — matching npm's behavior. Opt in with
includePrerelease:
satisfies("1.2.3-beta", "^1.0.0"); // false
satisfies("1.2.3-beta", "^1.2.3-alpha"); // true
satisfies("1.2.3-beta", "^1.0.0", { includePrerelease: true }); // trueinc("1.2.3", "minor"); // "1.3.0"
inc("1.2.3", "prerelease"); // "1.2.4-0"
inc("1.2.3-beta.1", "prerelease"); // "1.2.3-beta.2"
inc("1.2.3", "preminor", "beta"); // "1.3.0-beta.0"| Function | Description |
|---|---|
parse(v) / valid(v) / format(s) |
Parse, validate, render. |
compare(a, b) |
-1 | 0 | 1 by SemVer precedence (build ignored). |
eq neq gt gte lt lte |
Boolean comparisons. |
sort(list) / rsort(list) |
Ascending / descending sort. |
satisfies(v, range, opts?) |
Range test. |
validRange(range) |
Is the range parseable? |
maxSatisfying / minSatisfying(list, range, opts?) |
Best match. |
inc(v, release, identifier?) |
Bump major/minor/patch/pre*. |
Range |
The parsed-range class, if you want to reuse it. |
verspec |
hand-rolled compare | the classic semver pkg |
|
|---|---|---|---|
| Prerelease precedence | ✅ | ✅ | |
| Full range syntax | ✅ | ❌ | ✅ |
| Prerelease-in-range rule | ✅ | ❌ | ✅ |
| Zero dependencies | ✅ | ✅ | |
| ~2 KB gzipped | ✅ | ✅ | ❌ |
Contributions are very welcome! Please read CONTRIBUTING.md and our Code of Conduct.
git clone https://github.com/didrod205/verspec.git
cd verspec
npm install
npm testverspec is free and MIT-licensed, built and maintained in spare time. If it
saved you from a versioning headache, please consider supporting it — every bit
helps keep the project healthy.
- ⭐ Star this repo — the simplest, free way to help others discover it.
- 🍋 Sponsor via Lemon Squeezy — one-time or recurring support.
Sponsoring? Open an issue and we'll add your name/logo here. Thank you! 🙏
MIT © verspec contributors