◉ Pulse
sxzz avatar
#59 today ▲ 37

sxzz/verkit

TypeScript Library #esm #functional #immutable #range

Fast, zero-dependency SemVer for ESM and TypeScript, with functional, tree-shakeable APIs.

Created Jul 19, 2026
Stars
20
Today
+1
Forks
0
Quality
98/100
Momentum
38

README

Fetched from GitHub on Oct 30, 2026, 11:03 PM UTC · README.md

View original on GitHub

Third-party content — Open Source Pulse is not the owner of this repository.

This README belongs to sxzz/verkit and its contributors. We fetch it directly from the project’s public GitHub repository and display it for reference only. All text, code, images and trademarks remain the property of their respective authors. See the repository for its license terms. Copyright / takedown policy.

verkit

Open on npmx npm downloads Unit Test Codecov

Fast, zero-dependency SemVer for ESM and TypeScript, with functional, tree-shakeable APIs.

Features

  • ✅ Complete SemVer version and range toolkit.
  • 🚀 Faster than node-semver across tested operations.
  • 📦 Pure ESM with zero runtime dependencies.
  • 💙 First-class TypeScript declarations.
  • 🌳 Functional, tree-shakeable named exports.
  • 🔁 Mutable SemVer and SemVerRange records.
  • ⚡ 26.0% smaller for full CDN imports.
  • 🪶 61.4% smaller with common bundled imports.
  • 🛡️ Immutable collection operations.

Install

npm add verkit

Versions

import {
  coerce,
  increment,
  normalize,
  normalizeFull,
  parse,
  truncate,
} from 'verkit'

const version = parse('1.2.3-rc.1+sha.abc')
const coerced = coerce('release 42.6.7.9', { rtl: true })
version.patch = 4

normalizeFull(version) // '1.2.4-rc.1+sha.abc'
normalize(version) // '1.2.4-rc.1'
increment(version, 'minor') // '1.3.0'
truncate(version, 'patch') // '1.2.4'
coerced?.major // 6

Version APIs accept strings or mutable SemVer objects returned by parse or coerce. normalizeFull keeps build metadata; normalized, incremented, and truncated versions omit it.

Comparison

import { compare, compareBuild, isGreaterThan, sortReversed } from 'verkit'

compare('1.0.0+one', '1.0.0+two') // 0
compareBuild('1.0.0+one', '1.0.0+two') // -1
isGreaterThan('2.0.0', '1.0.0') // true
sortReversed(['1.0.0', '2.0.0']) // ['2.0.0', '1.0.0']

compare ignores build metadata; compareBuild uses it as a tie-breaker.

Ranges

import {
  findMaxSatisfying,
  normalizeRange,
  parseRange,
  satisfies,
} from 'verkit'

const range = parseRange('^1.2.3')

normalizeRange(range) // '>=1.2.3 <2.0.0-0'
satisfies('1.5.0', range) // true
findMaxSatisfying(['1.2.3', '1.5.0', '2.0.0'], range) // '1.5.0'

Range APIs accept strings or mutable SemVerRange objects. They support comparators, unions, hyphens, wildcards, tilde, caret, loose parsing, and prereleases.

Range options are fixed when a SemVerRange is created. APIs that receive a parsed range use its stored options and do not accept another options argument:

const prereleases = parseRange('1.x', { includePrerelease: true })

satisfies('1.0.0-rc.1', prereleases) // true

To use different options, pass the original range string again or create another parsed range.

API

See the API reference.

Invalid input behavior

parse, parseComparator, and parseRange throw detailed TypeErrors. Their tryParse* wrappers return null; other safe transforms and predicates keep their documented null/false behavior.

Migrating from node-semver

Only renamed or reshaped node-semver APIs are listed; same-named functions such as clean, coerce, compare, and satisfies are omitted.

node-semver verkit
SemVer parse
parse tryParse
valid normalize
inc, diff increment, difference
major, minor, patch, prerelease getMajor, getMinor, getPatch, getPrerelease
rcompare, compareLoose, cmp compareReversed, compare with { loose: true }, compareWithOperator
eq, neq, gt, gte, lt, lte isEqual, isNotEqual, isGreaterThan, isGreaterThanOrEqual, isLessThan, isLessThanOrEqual
rsort sortReversed
rcompareIdentifiers compareIdentifiersReversed
Comparator SemVerComparator, parseComparator, tryParseComparator
Comparator formatting, test, and intersection normalizeComparator, satisfiesComparator, comparatorsIntersect
Range parseRange
toComparators, validRange rangeToComparators, normalizeRange
maxSatisfying, minSatisfying, minVersion findMaxSatisfying, findMinSatisfying, findMinimumForRange
outside, gtr, ltr isOutsideRange, isGreaterThanRange, isLessThanRange
intersects, subset rangesIntersect, isRangeSubset
RELEASE_TYPES INCREMENT_TYPES (also includes release)

valid returns a normalized string | null in node-semver, so its equivalent is normalize. Use isValid when you only need a boolean.

Use options objects such as { loose: true } and { identifier, identifierBase }. Range options belong to the string-parsing step; parsed SemVerRange objects already contain them.

Differences from node-semver

verkit follows node-semver semantics with four user-visible differences:

  • Array helpers never mutate their inputs.
  • Parsed SemVerRange objects retain their parse-time options. node-semver helpers may reparse a Range from raw using call-site options.
  • verkit is ESM-only, with no CommonJS, CLI, or NODE_DEBUG=semver output.
  • Error text, stack traces, and supported runtimes may differ.

Bundle size

Full package imports, minified with Rolldown:

Package Minified gzip Brotli
verkit 18,820 B 5,914 B 5,375 B
semver 24,424 B 7,427 B 6,765 B
verkit reduction 26.0% 20.4% 20.5%

Common validation, range, comparison, increment, and coercion imports, tree-shaken and minified with Rolldown:

Package Minified gzip Brotli
verkit 9,872 B 3,401 B 3,121 B
semver 25,577 B 7,500 B 6,835 B
verkit reduction 61.4% 54.7% 54.3%

Run pnpm test:size to reproduce the comparison.

Benchmarks

Measured on a MacBook Pro with an Apple M1 Max and 32 GB RAM. Higher is better.

Operation verkit ops/s semver ops/s Faster
Parse and normalize 3.67M 3.26M verkit 1.13×
Compare 3.09M 2.36M verkit 1.31×
Compare parsed versions 40.59M 28.62M verkit 1.42×
Increment 3.38M 2.03M verkit 1.66×
Coerce 2.77M 2.32M verkit 1.19×
Satisfy uncached ranges 148.5K 122.3K verkit 1.21×
Satisfy pre-parsed inputs 22.91M 7.20M verkit 3.18×

Range benchmarks either cycle through 1,001 inputs to avoid cache hits or parse once and reuse the resulting objects.

Run runtime benchmarks with pnpm bench.

Sponsors

Sponsors

License

MIT © 2026-PRESENT Kevin Deng.

Parts of the implementation and test fixtures are derived from node-semver under the ISC license; see THIRD_PARTY_NOTICES.md.

Rendered by GitHub from the repository’s README. Scroll to read the full file.
First trending

Jul 20, 2026

first spotted on the list

Best rank

#27

highest position reached

Appearances

3

times on the trending list

Quality score

98

out of 100

Momentum

38

trend strength indicator

Star velocity

0.19

stars per day since creation

Activity — last 60 days

daily counts, collected every 6 hours
  • Stars
  • Forks
  • Merged PRs
  • Issues
  • Closed issues

Collecting activity data since launch — check back in a few days.

Star history

total stars per snapshot
10121416182022sxzz/verkit · Jul 20, 3 AM UTC: 12 starssxzz/verkit · Jul 20, 9 AM UTC: 19 starssxzz/verkit · Jul 20, 2 PM UTC: 20 stars3 AM8 AM2 PM

Rank history

position on trending · lower is better
#1#25#30#35#40#45#50#55#60Jul 20, 3 AM UTC: rank #27Jul 20, 9 AM UTC: rank #52Jul 20, 2 PM UTC: rank #593 AM8 AM2 PM

3D card for your website

Live HTML card with a glass surface and pointer tilt. Paste the iframe on any website.

<iframe src="https://www.notionpulse.cc/embed/sxzz/verkit" width="420" height="240" style="border:0;max-width:100%;background:transparent" loading="lazy" title="sxzz/verkit — trending on Open Source Pulse"></iframe>

Stars badge

Show current stars in your README or profile. Auto-updates every 6 hours.

sxzz/verkit stars badge
Markdown
[![sxzz/verkit](https://www.notionpulse.cc/api/badge/sxzz/verkit.svg)](https://www.notionpulse.cc/repo/sxzz/verkit)
HTML
<a href="https://www.notionpulse.cc/repo/sxzz/verkit"><img src="https://www.notionpulse.cc/api/badge/sxzz/verkit.svg" alt="sxzz/verkit stars badge" /></a>

Repository of the Day

#27 Repository of the Day

Repository of the Week

#27 Repository of the Week

Repository of the Month

#27 Repository of the Month