@hyperfrontend/versioning/semver

semver/

Semantic versioning utilities for parsing, comparing, formatting, and incrementing versions.

Overview

Complete implementation of the Semantic Versioning 2.0.0 specification. Parsing uses character-by-character state machines for predictable O(n) performance.

Usage Examples

Parsing Versions

import { parseVersion, parseVersionOrThrow, coerceVersion } from '@hyperfrontend/versioning'

// Safe parsing (returns null on invalid)
const v1 = parseVersion('1.2.3') // SemVer { major: 1, minor: 2, patch: 3 }
const v2 = parseVersion('invalid') // null

// Strict parsing (throws on invalid)
const v3 = parseVersionOrThrow('2.0.0-beta.1')

// Coerce with best effort
const v4 = coerceVersion('v1.2.3') // strips 'v' prefix
const v5 = coerceVersion('1.2') // normalizes to 1.2.0

Comparing Versions

import { compare, gt, lt, satisfies, parseVersion, parseRange } from '@hyperfrontend/versioning'

const a = parseVersion('1.0.0')!
const b = parseVersion('2.0.0')!

compare(a, b) // -1 (a < b)
gt(b, a) // true
lt(a, b) // true

// Range satisfaction
const range = parseRange('^1.0.0')!
satisfies(parseVersion('1.5.0')!, range) // true
satisfies(parseVersion('2.0.0')!, range) // false

Incrementing Versions

import { bump, parseVersion, format } from '@hyperfrontend/versioning'

const version = parseVersion('1.2.3')!

format(bump(version, 'major')) // '2.0.0'
format(bump(version, 'minor')) // '1.3.0'
format(bump(version, 'patch')) // '1.2.4'
format(bump(version, 'prerelease')) // '1.2.4-0'

Sorting Versions

import { sort, max, min, parseVersion, format } from '@hyperfrontend/versioning'

const versions = [parseVersion('2.0.0')!, parseVersion('1.0.0')!, parseVersion('1.5.0')!]

sort(versions).map(format) // ['1.0.0', '1.5.0', '2.0.0']
format(max(versions)!) // '2.0.0'
format(min(versions)!) // '1.0.0'

Design Principles

  1. Immutable — All operations return new objects
  2. Pure Functions — No side effects, deterministic output
  3. No Regex — Character-by-character parsing eliminates ReDoS
  4. Null Safety — Parse functions return null on invalid input
  5. Factory Pattern — Use create* functions for object construction

See Also

API Reference

ƒ Functions

§function

coerceVersion(input: string): SemVer

Attempts to coerce a string into a valid semver. More lenient than parseVersion - accepts partial versions.

Parameters

NameTypeDescription
§input
string
The string to coerce

Returns

SemVer
The parsed SemVer or null if coercion failed

Example

Coerce partial versions to valid semver
coerceVersion('1') // { major: 1, minor: 0, patch: 0, ... }
coerceVersion('1.2') // { major: 1, minor: 2, patch: 0, ... }
coerceVersion('v2.0') // { major: 2, minor: 0, patch: 0, ... }
§function

compare(a: SemVer, b: SemVer): -1 | 0 | 1

Compares two semantic versions.

Parameters

NameTypeDescription
SemVer
First version
SemVer
Second version

Returns

-1 | 0 | 1
-1 if a < b, 0 if a == b, 1 if a > b

Example

Compare two semantic versions
compare(parseVersion('1.0.0'), parseVersion('2.0.0')) // -1
compare(parseVersion('1.0.0'), parseVersion('1.0.0')) // 0
compare(parseVersion('2.0.0'), parseVersion('1.0.0')) // 1
§function

createAnyRange(): Range

Creates a range that matches any version.

Returns

Range
A Range matching any version (*)

Example

Create a range that matches any version

const anyRange = createAnyRange()
satisfies(parseVersionStrict('999.999.999'), anyRange) // => true
§function

createComparator(operator: RangeOperator, version: SemVer): Comparator

Creates a new Comparator.

Parameters

NameTypeDescription
§operator
RangeOperator
The comparison operator
§version
SemVer
The version to compare against

Returns

Comparator
A new Comparator

Example

Create a comparator for version comparison

createComparator('>=', parseVersionStrict('1.0.0'))
// => { operator: '>=', version: { major: 1, minor: 0, patch: 0, ... } }
§function

createComparatorSet(comparators: unknown): ComparatorSet

Creates a new ComparatorSet.

Parameters

NameTypeDescription
§comparators
unknown
Array of comparators (AND logic)

Returns

ComparatorSet
A new ComparatorSet

Example

Create a comparator set with AND logic

createComparatorSet([gte100, lt200]) // AND: >=1.0.0 AND <2.0.0
§function

createExactRange(version: SemVer): Range

Creates a range that matches exactly one version.

Parameters

NameTypeDescription
§version
SemVer
The exact version to match

Returns

Range
A Range matching exactly the specified version

Example

Create a range that matches exactly one version

const exact = createExactRange(parseVersionStrict('1.2.3'))
satisfies(parseVersionStrict('1.2.3'), exact) // => true
satisfies(parseVersionStrict('1.2.4'), exact) // => false
§function

createFirstRelease(): SemVer

Creates a SemVer representing version 1.0.0.

Returns

SemVer
A SemVer at version 1.0.0

Example

Create first 1.0.0 release version

const first = createFirstRelease()
format(first) // => '1.0.0'
§function

createInitialVersion(): SemVer

Creates a SemVer representing version 0.0.0.

Returns

SemVer
A SemVer at version 0.0.0

Example

Create initial 0.0.0 version

const initial = createInitialVersion()
format(initial) // => '0.0.0'
§function

createRange(sets: unknown, raw?: string): Range

Creates a new Range.

Parameters

NameTypeDescription
§sets
unknown
Array of comparator sets (OR logic)
§raw?
string
Original raw string

Returns

Range
A new Range

Example

Create a range with OR logic between sets

createRange([set1, set2], '>=1.0.0 || >=2.0.0 <3.0.0')
§function

createSemVer(options: Partial<SemVer> & RequiredVersionComponents): SemVer

Creates a new SemVer object.

Parameters

NameTypeDescription
§options
Partial<SemVer> & RequiredVersionComponents
Version components

Returns

SemVer
A new SemVer object

Example

Create a SemVer object from components

createSemVer({ major: 1, minor: 2, patch: 3 })
// => { major: 1, minor: 2, patch: 3, prerelease: [], build: [] }
createSemVer({ major: 1, minor: 0, patch: 0, prerelease: ['beta', '1'] })
// => 1.0.0-beta.1
§function

diff(older: SemVer, newer: SemVer): BumpType

Calculates the difference type between two versions.

Parameters

NameTypeDescription
§older
SemVer
The older version
§newer
SemVer
The newer version

Returns

BumpType
The type of difference, or null if versions are equal

Example

Calculate the difference type between two versions
diff(parseVersion('1.0.0'), parseVersion('2.0.0')) // 'major'
diff(parseVersion('1.0.0'), parseVersion('1.1.0')) // 'minor'
diff(parseVersion('1.0.0'), parseVersion('1.0.1')) // 'patch'
§function

eq(a: SemVer, b: SemVer): boolean

Checks if two versions are equal (ignoring build metadata).

Parameters

NameTypeDescription
SemVer
First version
SemVer
Second version

Returns

boolean
True if versions are equal

Example

Check if two versions are equal

eq(parseVersionStrict('1.0.0'), parseVersionStrict('1.0.0')) // => true
eq(parseVersionStrict('1.0.0'), parseVersionStrict('1.0.1')) // => false
§function

format(version: SemVer): string

Converts a SemVer to its canonical string representation.

Parameters

NameTypeDescription
§version
SemVer
The version to format

Returns

string
The version string (e.g., "1.2.3-alpha.1+build.123")

Example

Format a version to its canonical string

format(parseVersionStrict('1.2.3')) // => '1.2.3'
format(createSemVer({ major: 1, minor: 0, patch: 0, prerelease: ['beta', '1'] }))
// => '1.0.0-beta.1'
§function

formatComparator(comparator: Comparator): string

Converts a Comparator to its string representation.

Parameters

NameTypeDescription
§comparator
Comparator
The comparator to format

Returns

string
The comparator string (e.g., ">=1.0.0")

Example

Format a comparator to its string representation

formatComparator(createComparator('>=', parseVersionStrict('1.0.0')))
// => '>=1.0.0'
§function

formatRange(range: Range): string

Converts a Range to its string representation.

Parameters

NameTypeDescription
§range
Range
The range to format

Returns

string
The range string

Example

Format a range to its string representation

formatRange(parseRangeStrict('^1.0.0')) // => '^1.0.0'
formatRange(createAnyRange()) // => '*'
§function

formatSimple(version: SemVer): string

Converts a SemVer to a string without prerelease/build.

Parameters

NameTypeDescription
§version
SemVer
The version to format

Returns

string
The version string (e.g., "1.2.3")

Example

Format version without prerelease/build metadata

formatSimple(parseVersionStrict('1.2.3-beta.1+build')) // => '1.2.3'
§function

gt(a: SemVer, b: SemVer): boolean

Checks if a > b.

Parameters

NameTypeDescription
SemVer
First version to compare
SemVer
Second version to compare

Returns

boolean
True if a is greater than b

Example

Check if version a is greater than b

gt(parseVersionStrict('2.0.0'), parseVersionStrict('1.0.0')) // => true
gt(parseVersionStrict('1.0.0'), parseVersionStrict('2.0.0')) // => false
§function

gte(a: SemVer, b: SemVer): boolean

Checks if a >= b.

Parameters

NameTypeDescription
SemVer
First version to compare
SemVer
Second version to compare

Returns

boolean
True if a is greater than or equal to b

Example

Check if version a is greater than or equal to b

gte(parseVersionStrict('2.0.0'), parseVersionStrict('1.0.0')) // => true
gte(parseVersionStrict('1.0.0'), parseVersionStrict('1.0.0')) // => true
§function

increment(version: SemVer, type: BumpType, prereleaseId?: string): SemVer

Increments a version based on the bump type.

Parameters

NameTypeDescription
§version
SemVer
The version to increment
§type
BumpType
The type of bump (major, minor, patch, etc.)
§prereleaseId?
string
Optional prerelease identifier for prerelease bumps

Returns

SemVer
A new incremented SemVer

Example

Increment version by bump type
increment(parseVersion('1.2.3'), 'minor') // 1.3.0
increment(parseVersion('1.2.3'), 'major') // 2.0.0
increment(parseVersion('1.2.3'), 'prerelease', 'alpha') // 1.2.4-alpha.0
§function

incrementPrerelease(version: SemVer, id?: string): SemVer

Increments the prerelease portion of a version.

Parameters

NameTypeDescription
§version
SemVer
The version to increment
§id?
string
Optional prerelease identifier

Returns

SemVer
A new version with incremented prerelease

Example

Increment the prerelease portion of a version

incrementPrerelease(parseVersionStrict('1.0.0')) // => 1.0.1-alpha.0
incrementPrerelease(parseVersionStrict('1.0.0-alpha.0')) // => 1.0.0-alpha.1
incrementPrerelease(parseVersionStrict('1.0.0'), 'beta') // => 1.0.1-beta.0
§function

isPrerelease(version: SemVer): boolean

Checks if the version has prerelease identifiers.

Parameters

NameTypeDescription
§version
SemVer
The version to check

Returns

boolean
True if version has prerelease identifiers

Example

Check if version has prerelease identifiers

isPrerelease(parseVersionStrict('1.0.0-beta.1')) // => true
isPrerelease(parseVersionStrict('1.0.0')) // => false
§function

isStable(version: SemVer): boolean

Checks if the version is a stable release (>= 1.0.0 with no prerelease).

Parameters

NameTypeDescription
§version
SemVer
The version to check

Returns

boolean
True if version is stable

Example

Check if version is a stable release

isStable(parseVersionStrict('1.0.0')) // => true
isStable(parseVersionStrict('0.9.0')) // => false (< 1.0.0)
isStable(parseVersionStrict('1.0.0-beta')) // => false (prerelease)
§function

isWildcard(range: Range): boolean

Checks if a range represents a wildcard/any match.

Parameters

NameTypeDescription
§range
Range
The range to check

Returns

boolean
True if the range matches any version

Example

Check if a range represents a wildcard

isWildcard(parseRangeStrict('*')) // => true
isWildcard(parseRangeStrict('^1.0.0')) // => false
§function

lt(a: SemVer, b: SemVer): boolean

Checks if a < b.

Parameters

NameTypeDescription
SemVer
First version to compare
SemVer
Second version to compare

Returns

boolean
True if a is less than b

Example

Check if version a is less than b

lt(parseVersionStrict('1.0.0'), parseVersionStrict('2.0.0')) // => true
lt(parseVersionStrict('2.0.0'), parseVersionStrict('1.0.0')) // => false
§function

lte(a: SemVer, b: SemVer): boolean

Checks if a <= b.

Parameters

NameTypeDescription
SemVer
First version to compare
SemVer
Second version to compare

Returns

boolean
True if a is less than or equal to b

Example

Check if version a is less than or equal to b

lte(parseVersionStrict('1.0.0'), parseVersionStrict('1.0.0')) // => true
lte(parseVersionStrict('1.0.0'), parseVersionStrict('2.0.0')) // => true
§function

max(versions: unknown): SemVer

Returns the maximum version from an array.

Parameters

NameTypeDescription
§versions
unknown
Array of versions

Returns

SemVer
The maximum version, or null if array is empty

Example

Get the maximum version from an array

const versions = [parseVersionStrict('1.0.0'), parseVersionStrict('2.0.0')]
max(versions) // => { major: 2, minor: 0, patch: 0, ... }
max([]) // => null
§function

maxSatisfying(versions: unknown, range: Range): SemVer

Finds the maximum version that satisfies a range.

Parameters

NameTypeDescription
§versions
unknown
Array of versions to check
§range
Range
Range to test against

Returns

SemVer
The maximum satisfying version, or null if none satisfy

Example

Find the maximum version satisfying a range

const versions = ['1.0.0', '1.5.0', '2.0.0'].map(parseVersionStrict)
maxSatisfying(versions, parseRangeStrict('^1.0.0'))
// => { major: 1, minor: 5, patch: 0, ... }
§function

min(versions: unknown): SemVer

Returns the minimum version from an array.

Parameters

NameTypeDescription
§versions
unknown
Array of versions

Returns

SemVer
The minimum version, or null if array is empty

Example

Get the minimum version from an array

const versions = [parseVersionStrict('1.0.0'), parseVersionStrict('2.0.0')]
min(versions) // => { major: 1, minor: 0, patch: 0, ... }
min([]) // => null
§function

minSatisfying(versions: unknown, range: Range): SemVer

Finds the minimum version that satisfies a range.

Parameters

NameTypeDescription
§versions
unknown
Array of versions to check
§range
Range
Range to test against

Returns

SemVer
The minimum satisfying version, or null if none satisfy

Example

Find the minimum version satisfying a range

const versions = ['1.0.0', '1.5.0', '2.0.0'].map(parseVersionStrict)
minSatisfying(versions, parseRangeStrict('^1.0.0'))
// => { major: 1, minor: 0, patch: 0, ... }
§function

neq(a: SemVer, b: SemVer): boolean

Checks if a != b.

Parameters

NameTypeDescription
SemVer
First version to compare
SemVer
Second version to compare

Returns

boolean
True if versions are not equal

Example

Check if two versions are not equal

neq(parseVersionStrict('1.0.0'), parseVersionStrict('2.0.0')) // => true
neq(parseVersionStrict('1.0.0'), parseVersionStrict('1.0.0')) // => false
§function

parseRange(input: string): ParseRangeResult

Parses a semver range string.
Supports:
  • Exact: 1.2.3, =1.2.3
  • Comparators: >1.0.0, >=1.0.0, <2.0.0, <=2.0.0
  • Caret: ^1.2.3 (compatible with version)
  • Tilde: ~1.2.3 (approximately equivalent)
  • X-ranges: 1.x, 1.2.x, *
  • Hyphen ranges: 1.0.0 - 2.0.0
  • OR: 1.0.0 || 2.0.0
  • AND: >=1.0.0 <2.0.0

Parameters

NameTypeDescription
§input
string
The range string to parse

Returns

ParseRangeResult
A ParseRangeResult with the parsed range or error

Example

Parse semver range strings

parseRange('^1.0.0') // => { success: true, range: ... }
parseRange('>=1.0.0 <2.0.0') // => { success: true, range: ... }
parseRange('1.0.0 || 2.0.0') // => { success: true, range: ... }
§function

parseRangeStrict(input: string): Range

Parses a range string, throwing on invalid input.

Parameters

NameTypeDescription
§input
string
The range string to parse

Returns

Range
The parsed Range

Example

Parse range with strict validation

const range = parseRangeStrict('^1.0.0')
parseRangeStrict('invalid range!!!') // throws Error
§function

parseVersion(input: string): ParseVersionResult

Parses a semantic version string.
Accepts versions in the format: MAJOR.MINOR.PATCH[-prerelease][+build] Optional leading 'v' or '=' prefixes are stripped.

Parameters

NameTypeDescription
§input
string
The version string to parse

Returns

ParseVersionResult
A ParseVersionResult with the parsed version or error

Example

Parse a semantic version string
parseVersion('1.2.3') // { success: true, version: { major: 1, minor: 2, patch: 3, ... } }
parseVersion('v1.0.0-alpha.1+build.123') // { success: true, ... }
parseVersion('invalid') // { success: false, error: '...' }
§function

parseVersionStrict(input: string): SemVer

Parses a version string, throwing on invalid input.

Parameters

NameTypeDescription
§input
string
The version string to parse

Returns

SemVer
The parsed SemVer

Example

Parse version with strict validation

const v = parseVersionStrict('1.2.3')
// => { major: 1, minor: 2, patch: 3, prerelease: [], build: [] }
parseVersionStrict('invalid') // throws Error
§function

satisfies(version: SemVer, range: Range): boolean

Checks if a version satisfies a range.

Parameters

NameTypeDescription
§version
SemVer
Version to check
§range
Range
Range to test against

Returns

boolean
True if version satisfies the range

Example

Check if version satisfies a range
satisfies(parseVersion('1.2.3'), parseRange('^1.0.0')) // true
satisfies(parseVersion('2.0.0'), parseRange('^1.0.0')) // false
§function

satisfiesComparator(version: SemVer, comparator: Comparator): boolean

Checks if a version satisfies a comparator.

Parameters

NameTypeDescription
§version
SemVer
Version to check
§comparator
Comparator
Comparator to test against

Returns

boolean
True if version satisfies the comparator

Example

Check if version satisfies a comparator

const gte100 = createComparator('>=', parseVersionStrict('1.0.0'))
satisfiesComparator(parseVersionStrict('2.0.0'), gte100) // => true
satisfiesComparator(parseVersionStrict('0.9.0'), gte100) // => false
§function

sort(versions: unknown): SemVer[]

Sorts an array of versions in ascending order.

Parameters

NameTypeDescription
§versions
unknown
Array of versions to sort

Returns

SemVer[]
A new sorted array

Example

Sort versions in ascending order
sort([v2, v1, v3]) // [v1, v2, v3]
§function

sortDescending(versions: unknown): SemVer[]

Sorts an array of versions in descending order.

Parameters

NameTypeDescription
§versions
unknown
Array of versions to sort

Returns

SemVer[]
A new sorted array

Example

Sort versions in descending order
sortDescending([v1, v3, v2]) // [v3, v2, v1]
§function

stripBuild(version: SemVer): SemVer

Returns a new version with build metadata stripped.

Parameters

NameTypeDescription
§version
SemVer
The version to strip

Returns

SemVer
A new SemVer without build metadata

Example

Strip build metadata from version

const v = parseVersionStrict('1.0.0+build.123')
format(stripBuild(v)) // => '1.0.0'
§function

stripPrerelease(version: SemVer): SemVer

Returns a new version with prerelease identifiers stripped.

Parameters

NameTypeDescription
§version
SemVer
The version to strip

Returns

SemVer
A new SemVer without prerelease identifiers

Example

Strip prerelease identifiers from version

const v = parseVersionStrict('1.0.0-beta.1')
format(stripPrerelease(v)) // => '1.0.0'

Interfaces

§interface

Comparator

A single comparator in a range set.
Examples:
  • >=1.2.3 -> { operator: '>=', version: { major: 1, minor: 2, patch: 3 } }
  • ^1.2.0 -> { operator: '^', version: { major: 1, minor: 2, patch: 0 } }

Properties

§readonly operator:RangeOperator
The comparison operator
§readonly version:SemVer
The version to compare against
§interface

ComparatorSet

A set of comparators that must all be satisfied. Represents the space-separated part of a range (AND logic).
Example: ">=1.0.0 <2.0.0" -> two comparators in one set

Properties

§readonly comparators:unknown
Array of comparators that must all be satisfied (AND logic).
§interface

ParseRangeResult

Result of parsing a range string.

Properties

§readonly error?:string
Error message (if failed)
§readonly range?:Range
The parsed range (if successful)
§readonly success:boolean
Whether parsing succeeded
§interface

ParseVersionResult

Result of parsing a version string.

Properties

§readonly error?:string
Error message (if failed)
§readonly success:boolean
Whether parsing succeeded
§readonly version?:SemVer
The parsed version (if successful)
§interface

Range

A version range that can contain multiple comparator sets. Represents the || separated parts (OR logic).
Example: "^1.0.0 || ^2.0.0" -> two comparator sets

Properties

§readonly raw?:string
Original raw string if parsed
§readonly sets:unknown
Comparator sets (OR logic between sets, AND logic within)
§interface

SemVer

Semantic Version
A version number in the format MAJOR.MINOR.PATCH with optional prerelease and build metadata.

Properties

§readonly build:unknown
Build metadata identifiers (e.g., ["build", "123"])
§readonly major:number
Major version - incremented for breaking changes
§readonly minor:number
Minor version - incremented for new features
§readonly patch:number
Patch version - incremented for bug fixes
§readonly prerelease:unknown
Prerelease identifiers (e.g., ["alpha", "1"])
§readonly raw?:string
Original raw string if parsed

Types

§type

BumpType

Bump type for version increments.
type BumpType = "major" | "minor" | "patch" | "premajor" | "preminor" | "prepatch" | "prerelease" | "none"
§type

RangeOperator

Comparison operator for version ranges.
type RangeOperator = "=" | ">" | ">=" | "<" | "<=" | "^" | "~"